From: =?utf-8?q?Ond=C5=99ej_Sur=C3=BD?= <ondrej@sury.org>
Date: Tue, 28 Jun 2016 12:36:19 +0200
Subject: Use system ldns library for compilation

---
 MANIFEST                          |   99 +-
 Makefile.PL                       |   19 +-
 include/ldns/buffer.h             |  645 ---------
 include/ldns/common.h             |   78 --
 include/ldns/config.h             |  590 --------
 include/ldns/dane.h               |  262 ----
 include/ldns/dname.h              |  211 ---
 include/ldns/dnssec.h             |  541 --------
 include/ldns/dnssec_sign.h        |  383 ------
 include/ldns/dnssec_verify.h      |  857 ------------
 include/ldns/dnssec_zone.h        |  483 -------
 include/ldns/duration.h           |  109 --
 include/ldns/error.h              |  147 --
 include/ldns/higher.h             |  113 --
 include/ldns/host2str.h           |  891 ------------
 include/ldns/host2wire.h          |  197 ---
 include/ldns/keys.h               |  621 ---------
 include/ldns/ldns.h               |  158 ---
 include/ldns/net.h                |  207 ---
 include/ldns/packet.h             |  891 ------------
 include/ldns/parse.h              |  167 ---
 include/ldns/radix.h              |  240 ----
 include/ldns/rbtree.h             |  230 ----
 include/ldns/rdata.h              |  451 -------
 include/ldns/resolver.h           |  805 -----------
 include/ldns/rr.h                 |  929 -------------
 include/ldns/rr_functions.h       |  363 -----
 include/ldns/sha1.h               |   38 -
 include/ldns/sha2.h               |  149 --
 include/ldns/str2host.h           |  319 -----
 include/ldns/tsig.h               |  101 --
 include/ldns/update.h             |  115 --
 include/ldns/util.h               |  392 ------
 include/ldns/wire2host.h          |  197 ---
 include/ldns/zone.h               |  176 ---
 ldns/include/ldns/buffer.h        |  645 +++++++++
 ldns/include/ldns/common.h        |   78 ++
 ldns/include/ldns/config.h        |  590 ++++++++
 ldns/include/ldns/dane.h          |  262 ++++
 ldns/include/ldns/dname.h         |  211 +++
 ldns/include/ldns/dnssec.h        |  541 ++++++++
 ldns/include/ldns/dnssec_sign.h   |  383 ++++++
 ldns/include/ldns/dnssec_verify.h |  857 ++++++++++++
 ldns/include/ldns/dnssec_zone.h   |  483 +++++++
 ldns/include/ldns/duration.h      |  109 ++
 ldns/include/ldns/error.h         |  147 ++
 ldns/include/ldns/higher.h        |  113 ++
 ldns/include/ldns/host2str.h      |  891 ++++++++++++
 ldns/include/ldns/host2wire.h     |  197 +++
 ldns/include/ldns/keys.h          |  621 +++++++++
 ldns/include/ldns/ldns.h          |  158 +++
 ldns/include/ldns/net.h           |  207 +++
 ldns/include/ldns/packet.h        |  891 ++++++++++++
 ldns/include/ldns/parse.h         |  167 +++
 ldns/include/ldns/radix.h         |  240 ++++
 ldns/include/ldns/rbtree.h        |  230 ++++
 ldns/include/ldns/rdata.h         |  451 +++++++
 ldns/include/ldns/resolver.h      |  805 +++++++++++
 ldns/include/ldns/rr.h            |  929 +++++++++++++
 ldns/include/ldns/rr_functions.h  |  363 +++++
 ldns/include/ldns/sha1.h          |   38 +
 ldns/include/ldns/sha2.h          |  149 ++
 ldns/include/ldns/str2host.h      |  319 +++++
 ldns/include/ldns/tsig.h          |  101 ++
 ldns/include/ldns/update.h        |  115 ++
 ldns/include/ldns/util.h          |  392 ++++++
 ldns/include/ldns/wire2host.h     |  197 +++
 ldns/include/ldns/zone.h          |  176 +++
 ldns/src/buffer.c                 |  177 +++
 ldns/src/compat/b64_ntop.c        |  185 +++
 ldns/src/compat/b64_pton.c        |  244 ++++
 ldns/src/compat/strlcpy.c         |   57 +
 ldns/src/dane.c                   |  748 ++++++++++
 ldns/src/dname.c                  |  598 ++++++++
 ldns/src/dnssec.c                 | 1869 +++++++++++++++++++++++++
 ldns/src/dnssec_sign.c            | 1456 ++++++++++++++++++++
 ldns/src/dnssec_verify.c          | 2684 ++++++++++++++++++++++++++++++++++++
 ldns/src/dnssec_zone.c            | 1192 ++++++++++++++++
 ldns/src/duration.c               |  354 +++++
 ldns/src/error.c                  |  160 +++
 ldns/src/higher.c                 |  344 +++++
 ldns/src/host2str.c               | 2635 ++++++++++++++++++++++++++++++++++++
 ldns/src/host2wire.c              |  494 +++++++
 ldns/src/keys.c                   | 1726 +++++++++++++++++++++++
 ldns/src/net.c                    | 1002 ++++++++++++++
 ldns/src/packet.c                 | 1159 ++++++++++++++++
 ldns/src/parse.c                  |  434 ++++++
 ldns/src/radix.c                  | 1590 ++++++++++++++++++++++
 ldns/src/rbtree.c                 |  670 +++++++++
 ldns/src/rdata.c                  |  757 +++++++++++
 ldns/src/resolver.c               | 1603 ++++++++++++++++++++++
 ldns/src/rr.c                     | 2705 +++++++++++++++++++++++++++++++++++++
 ldns/src/rr_functions.c           |  419 ++++++
 ldns/src/sha1.c                   |  177 +++
 ldns/src/sha2.c                   |  991 ++++++++++++++
 ldns/src/str2host.c               | 1604 ++++++++++++++++++++++
 ldns/src/tsig.c                   |  470 +++++++
 ldns/src/update.c                 |  325 +++++
 ldns/src/util.c                   |  773 +++++++++++
 ldns/src/wire2host.c              |  491 +++++++
 ldns/src/zone.c                   |  318 +++++
 src/ldns/buffer.c                 |  177 ---
 src/ldns/compat/b64_ntop.c        |  185 ---
 src/ldns/compat/b64_pton.c        |  244 ----
 src/ldns/compat/strlcpy.c         |   57 -
 src/ldns/dane.c                   |  748 ----------
 src/ldns/dname.c                  |  598 --------
 src/ldns/dnssec.c                 | 1869 -------------------------
 src/ldns/dnssec_sign.c            | 1456 --------------------
 src/ldns/dnssec_verify.c          | 2684 ------------------------------------
 src/ldns/dnssec_zone.c            | 1192 ----------------
 src/ldns/duration.c               |  354 -----
 src/ldns/error.c                  |  160 ---
 src/ldns/higher.c                 |  344 -----
 src/ldns/host2str.c               | 2635 ------------------------------------
 src/ldns/host2wire.c              |  494 -------
 src/ldns/keys.c                   | 1726 -----------------------
 src/ldns/net.c                    | 1002 --------------
 src/ldns/packet.c                 | 1159 ----------------
 src/ldns/parse.c                  |  434 ------
 src/ldns/radix.c                  | 1590 ----------------------
 src/ldns/rbtree.c                 |  670 ---------
 src/ldns/rdata.c                  |  757 -----------
 src/ldns/resolver.c               | 1603 ----------------------
 src/ldns/rr.c                     | 2705 -------------------------------------
 src/ldns/rr_functions.c           |  419 ------
 src/ldns/sha1.c                   |  177 ---
 src/ldns/sha2.c                   |  991 --------------
 src/ldns/str2host.c               | 1604 ----------------------
 src/ldns/tsig.c                   |  470 -------
 src/ldns/update.c                 |  325 -----
 src/ldns/util.c                   |  773 -----------
 src/ldns/wire2host.c              |  491 -------
 src/ldns/zone.c                   |  318 -----
 134 files changed, 42518 insertions(+), 42534 deletions(-)
 delete mode 100644 include/ldns/buffer.h
 delete mode 100644 include/ldns/common.h
 delete mode 100644 include/ldns/config.h
 delete mode 100644 include/ldns/dane.h
 delete mode 100644 include/ldns/dname.h
 delete mode 100644 include/ldns/dnssec.h
 delete mode 100644 include/ldns/dnssec_sign.h
 delete mode 100644 include/ldns/dnssec_verify.h
 delete mode 100644 include/ldns/dnssec_zone.h
 delete mode 100644 include/ldns/duration.h
 delete mode 100644 include/ldns/error.h
 delete mode 100644 include/ldns/higher.h
 delete mode 100644 include/ldns/host2str.h
 delete mode 100644 include/ldns/host2wire.h
 delete mode 100644 include/ldns/keys.h
 delete mode 100644 include/ldns/ldns.h
 delete mode 100644 include/ldns/net.h
 delete mode 100644 include/ldns/packet.h
 delete mode 100644 include/ldns/parse.h
 delete mode 100644 include/ldns/radix.h
 delete mode 100644 include/ldns/rbtree.h
 delete mode 100644 include/ldns/rdata.h
 delete mode 100644 include/ldns/resolver.h
 delete mode 100644 include/ldns/rr.h
 delete mode 100644 include/ldns/rr_functions.h
 delete mode 100644 include/ldns/sha1.h
 delete mode 100644 include/ldns/sha2.h
 delete mode 100644 include/ldns/str2host.h
 delete mode 100644 include/ldns/tsig.h
 delete mode 100644 include/ldns/update.h
 delete mode 100644 include/ldns/util.h
 delete mode 100644 include/ldns/wire2host.h
 delete mode 100644 include/ldns/zone.h
 create mode 100644 ldns/include/ldns/buffer.h
 create mode 100644 ldns/include/ldns/common.h
 create mode 100644 ldns/include/ldns/config.h
 create mode 100644 ldns/include/ldns/dane.h
 create mode 100644 ldns/include/ldns/dname.h
 create mode 100644 ldns/include/ldns/dnssec.h
 create mode 100644 ldns/include/ldns/dnssec_sign.h
 create mode 100644 ldns/include/ldns/dnssec_verify.h
 create mode 100644 ldns/include/ldns/dnssec_zone.h
 create mode 100644 ldns/include/ldns/duration.h
 create mode 100644 ldns/include/ldns/error.h
 create mode 100644 ldns/include/ldns/higher.h
 create mode 100644 ldns/include/ldns/host2str.h
 create mode 100644 ldns/include/ldns/host2wire.h
 create mode 100644 ldns/include/ldns/keys.h
 create mode 100644 ldns/include/ldns/ldns.h
 create mode 100644 ldns/include/ldns/net.h
 create mode 100644 ldns/include/ldns/packet.h
 create mode 100644 ldns/include/ldns/parse.h
 create mode 100644 ldns/include/ldns/radix.h
 create mode 100644 ldns/include/ldns/rbtree.h
 create mode 100644 ldns/include/ldns/rdata.h
 create mode 100644 ldns/include/ldns/resolver.h
 create mode 100644 ldns/include/ldns/rr.h
 create mode 100644 ldns/include/ldns/rr_functions.h
 create mode 100644 ldns/include/ldns/sha1.h
 create mode 100644 ldns/include/ldns/sha2.h
 create mode 100644 ldns/include/ldns/str2host.h
 create mode 100644 ldns/include/ldns/tsig.h
 create mode 100644 ldns/include/ldns/update.h
 create mode 100644 ldns/include/ldns/util.h
 create mode 100644 ldns/include/ldns/wire2host.h
 create mode 100644 ldns/include/ldns/zone.h
 create mode 100644 ldns/src/buffer.c
 create mode 100644 ldns/src/compat/b64_ntop.c
 create mode 100644 ldns/src/compat/b64_pton.c
 create mode 100644 ldns/src/compat/strlcpy.c
 create mode 100644 ldns/src/dane.c
 create mode 100644 ldns/src/dname.c
 create mode 100644 ldns/src/dnssec.c
 create mode 100644 ldns/src/dnssec_sign.c
 create mode 100644 ldns/src/dnssec_verify.c
 create mode 100644 ldns/src/dnssec_zone.c
 create mode 100644 ldns/src/duration.c
 create mode 100644 ldns/src/error.c
 create mode 100644 ldns/src/higher.c
 create mode 100644 ldns/src/host2str.c
 create mode 100644 ldns/src/host2wire.c
 create mode 100644 ldns/src/keys.c
 create mode 100644 ldns/src/net.c
 create mode 100644 ldns/src/packet.c
 create mode 100644 ldns/src/parse.c
 create mode 100644 ldns/src/radix.c
 create mode 100644 ldns/src/rbtree.c
 create mode 100644 ldns/src/rdata.c
 create mode 100644 ldns/src/resolver.c
 create mode 100644 ldns/src/rr.c
 create mode 100644 ldns/src/rr_functions.c
 create mode 100644 ldns/src/sha1.c
 create mode 100644 ldns/src/sha2.c
 create mode 100644 ldns/src/str2host.c
 create mode 100644 ldns/src/tsig.c
 create mode 100644 ldns/src/update.c
 create mode 100644 ldns/src/util.c
 create mode 100644 ldns/src/wire2host.c
 create mode 100644 ldns/src/zone.c
 delete mode 100644 src/ldns/buffer.c
 delete mode 100644 src/ldns/compat/b64_ntop.c
 delete mode 100644 src/ldns/compat/b64_pton.c
 delete mode 100644 src/ldns/compat/strlcpy.c
 delete mode 100644 src/ldns/dane.c
 delete mode 100644 src/ldns/dname.c
 delete mode 100644 src/ldns/dnssec.c
 delete mode 100644 src/ldns/dnssec_sign.c
 delete mode 100644 src/ldns/dnssec_verify.c
 delete mode 100644 src/ldns/dnssec_zone.c
 delete mode 100644 src/ldns/duration.c
 delete mode 100644 src/ldns/error.c
 delete mode 100644 src/ldns/higher.c
 delete mode 100644 src/ldns/host2str.c
 delete mode 100644 src/ldns/host2wire.c
 delete mode 100644 src/ldns/keys.c
 delete mode 100644 src/ldns/net.c
 delete mode 100644 src/ldns/packet.c
 delete mode 100644 src/ldns/parse.c
 delete mode 100644 src/ldns/radix.c
 delete mode 100644 src/ldns/rbtree.c
 delete mode 100644 src/ldns/rdata.c
 delete mode 100644 src/ldns/resolver.c
 delete mode 100644 src/ldns/rr.c
 delete mode 100644 src/ldns/rr_functions.c
 delete mode 100644 src/ldns/sha1.c
 delete mode 100644 src/ldns/sha2.c
 delete mode 100644 src/ldns/str2host.c
 delete mode 100644 src/ldns/tsig.c
 delete mode 100644 src/ldns/update.c
 delete mode 100644 src/ldns/util.c
 delete mode 100644 src/ldns/wire2host.c
 delete mode 100644 src/ldns/zone.c

diff --git a/MANIFEST b/MANIFEST
index 580f068..a8b2463 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -9,39 +9,6 @@ inc/Module/Install/Win32.pm
 inc/Module/Install/WriteAll.pm
 inc/Module/Install/XSUtil.pm
 include/LDNS.h
-include/ldns/buffer.h
-include/ldns/common.h
-include/ldns/config.h
-include/ldns/dane.h
-include/ldns/dname.h
-include/ldns/dnssec.h
-include/ldns/dnssec_sign.h
-include/ldns/dnssec_verify.h
-include/ldns/dnssec_zone.h
-include/ldns/duration.h
-include/ldns/error.h
-include/ldns/higher.h
-include/ldns/host2str.h
-include/ldns/host2wire.h
-include/ldns/keys.h
-include/ldns/ldns.h
-include/ldns/net.h
-include/ldns/packet.h
-include/ldns/parse.h
-include/ldns/radix.h
-include/ldns/rbtree.h
-include/ldns/rdata.h
-include/ldns/resolver.h
-include/ldns/rr.h
-include/ldns/rr_functions.h
-include/ldns/sha1.h
-include/ldns/sha2.h
-include/ldns/str2host.h
-include/ldns/tsig.h
-include/ldns/update.h
-include/ldns/util.h
-include/ldns/wire2host.h
-include/ldns/zone.h
 lib/Net/LDNS.pm
 lib/Net/LDNS/Packet.pm
 lib/Net/LDNS/RR.pm
@@ -128,39 +95,6 @@ ppport.h
 README.md
 src/assist.c
 src/LDNS.xs
-src/ldns/compat/b64_ntop.c
-src/ldns/compat/b64_pton.c
-src/ldns/buffer.c
-src/ldns/compat/strlcpy.c
-src/ldns/dane.c
-src/ldns/dname.c
-src/ldns/dnssec.c
-src/ldns/dnssec_sign.c
-src/ldns/dnssec_verify.c
-src/ldns/dnssec_zone.c
-src/ldns/duration.c
-src/ldns/error.c
-src/ldns/higher.c
-src/ldns/host2str.c
-src/ldns/host2wire.c
-src/ldns/keys.c
-src/ldns/net.c
-src/ldns/packet.c
-src/ldns/parse.c
-src/ldns/radix.c
-src/ldns/rbtree.c
-src/ldns/rdata.c
-src/ldns/resolver.c
-src/ldns/rr.c
-src/ldns/rr_functions.c
-src/ldns/sha1.c
-src/ldns/sha2.c
-src/ldns/str2host.c
-src/ldns/tsig.c
-src/ldns/update.c
-src/ldns/util.c
-src/ldns/wire2host.c
-src/ldns/zone.c
 src/typemap
 t/axfr.t
 t/dnssec.t
@@ -176,3 +110,36 @@ t/rrlist.t
 t/serialize.t
 t/threads.t
 t/utils.t
+ldns/src/buffer.c
+ldns/src/compat/b64_ntop.c
+ldns/src/compat/b64_pton.c
+ldns/src/compat/strlcpy.c
+ldns/src/dane.c
+ldns/src/dname.c
+ldns/src/dnssec.c
+ldns/src/dnssec_sign.c
+ldns/src/dnssec_verify.c
+ldns/src/dnssec_zone.c
+ldns/src/duration.c
+ldns/src/error.c
+ldns/src/higher.c
+ldns/src/host2str.c
+ldns/src/host2wire.c
+ldns/src/keys.c
+ldns/src/net.c
+ldns/src/packet.c
+ldns/src/parse.c
+ldns/src/radix.c
+ldns/src/rbtree.c
+ldns/src/rdata.c
+ldns/src/resolver.c
+ldns/src/rr.c
+ldns/src/rr_functions.c
+ldns/src/sha1.c
+ldns/src/sha2.c
+ldns/src/str2host.c
+ldns/src/tsig.c
+ldns/src/update.c
+ldns/src/util.c
+ldns/src/wire2host.c
+ldns/src/zone.c
diff --git a/Makefile.PL b/Makefile.PL
index 35596f7..5ae48a9 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -75,6 +75,23 @@ else {
 
 if (
     check_lib(
+	lib      => 'ldns',
+	header   => 'ldns/ldns.h',
+	function => 'if (!ldns_resolver_clone(ldns_resolver_new())) return 1; else return 0;'
+    )
+  )
+{
+    print "Using system ldns library.\n";
+    cc_libs 'ldns';
+}
+else {
+    print "Using embedded ldns library.\n";
+    cc_include_paths 'ldns/include';
+    cc_src_paths 'ldns/src';
+}
+
+if (
+    check_lib(
         lib      => 'idn',
         header   => 'idna.h',
         function => 'if(strcmp(IDNA_ACE_PREFIX,"xn--")==0) return 0; else return 1;'
@@ -140,4 +157,4 @@ sub check_gost {
 CODE
 
     return check_lib(%args);
-}
\ No newline at end of file
+}
diff --git a/include/ldns/buffer.h b/include/ldns/buffer.h
deleted file mode 100644
index 3b64198..0000000
--- a/include/ldns/buffer.h
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * buffer.h -- generic memory buffer.
- *
- * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- *
- *
- * The buffer module implements a generic buffer.  The API is based on
- * the java.nio.Buffer interface.
- */
-
-#ifndef LDNS_BUFFER_H
-#define LDNS_BUFFER_H
-
-#include <assert.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include <ldns/error.h>
-#include <ldns/common.h>
-
-#include "ldns/util.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * number of initial bytes in buffer of
- * which we cannot tell the size before hand
- */
-#define LDNS_MIN_BUFLEN	512
-
-/**
- * \file buffer.h
- *
- * This file contains the definition of ldns_buffer, and functions to manipulate those.
- */
-
-/** 
- * implementation of buffers to ease operations
- *
- * ldns_buffers can contain arbitrary information, per octet. You can write
- * to the current end of a buffer, read from the current position, and
- * access any data within it.
- *
- * Example use of buffers is in the source code of \ref host2str.c
- */
-struct ldns_struct_buffer
-{
-	/** The current position used for reading/writing */ 
-	size_t   _position;
-
-	/** The read/write limit */
-	size_t   _limit;
-
-	/** The amount of data the buffer can contain */
-	size_t   _capacity;
-
-	/** The data contained in the buffer */
-	uint8_t *_data;
-
-	/** If the buffer is fixed it cannot be resized */
-	unsigned _fixed : 1;
-
-	/** The current state of the buffer. If writing to the buffer fails
-	 * for any reason, this value is changed. This way, you can perform
-	 * multiple writes in sequence and check for success afterwards. */
-	ldns_status _status;
-};
-typedef struct ldns_struct_buffer ldns_buffer;
-
-
-#ifdef NDEBUG
-INLINE void
-ldns_buffer_invariant(ldns_buffer *ATTR_UNUSED(buffer))
-{
-}
-#else
-INLINE void
-ldns_buffer_invariant(ldns_buffer *buffer)
-{
-	assert(buffer != NULL);
-	assert(buffer->_position <= buffer->_limit);
-	assert(buffer->_limit <= buffer->_capacity);
-	assert(buffer->_data != NULL);
-}
-#endif
-
-/**
- * creates a new buffer with the specified capacity.
- *
- * \param[in] capacity the size (in bytes) to allocate for the buffer
- * \return the created buffer
- */
-ldns_buffer *ldns_buffer_new(size_t capacity);
-
-/**
- * creates a buffer with the specified data.  The data IS copied
- * and MEMORY allocations are done.  The buffer is not fixed and can
- * be resized using buffer_reserve().
- *
- * \param[in] buffer pointer to the buffer to put the data in
- * \param[in] data the data to encapsulate in the buffer
- * \param[in] size the size of the data
- */
-void ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size);
-
-/**
- * clears the buffer and make it ready for writing.  The buffer's limit
- * is set to the capacity and the position is set to 0.
- * \param[in] buffer the buffer to clear
- */
-INLINE void ldns_buffer_clear(ldns_buffer *buffer)
-{
-	ldns_buffer_invariant(buffer);
-
-	/* reset status here? */
-
-	buffer->_position = 0;
-	buffer->_limit = buffer->_capacity;
-}
-
-/**
- * makes the buffer ready for reading the data that has been written to
- * the buffer.  The buffer's limit is set to the current position and
- * the position is set to 0.
- *
- * \param[in] buffer the buffer to flip
- * \return void
- */
-INLINE void ldns_buffer_flip(ldns_buffer *buffer)
-{
-	ldns_buffer_invariant(buffer);
-
-	buffer->_limit = buffer->_position;
-	buffer->_position = 0;
-}
-
-/**
- * make the buffer ready for re-reading the data.  The buffer's
- * position is reset to 0.
- * \param[in] buffer the buffer to rewind
- */
-INLINE void ldns_buffer_rewind(ldns_buffer *buffer)
-{
-	ldns_buffer_invariant(buffer);
-
-	buffer->_position = 0;
-}
-
-/**
- * returns the current position in the buffer (as a number of bytes)
- * \param[in] buffer the buffer
- * \return the current position
- */
-INLINE size_t
-ldns_buffer_position(ldns_buffer *buffer)
-{
-	return buffer->_position;
-}
-
-/**
- * sets the buffer's position to MARK.  The position must be less than
- * or equal to the buffer's limit.
- * \param[in] buffer the buffer
- * \param[in] mark the mark to use
- */
-INLINE void
-ldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
-{
-	assert(mark <= buffer->_limit);
-	buffer->_position = mark;
-}
-
-/**
- * changes the buffer's position by COUNT bytes.  The position must not
- * be moved behind the buffer's limit or before the beginning of the
- * buffer.
- * \param[in] buffer the buffer
- * \param[in] count the count to use
- */
-INLINE void
-ldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
-{
-	assert(buffer->_position + count <= buffer->_limit);
-	buffer->_position += count;
-}
-
-/**
- * returns the maximum size of the buffer
- * \param[in] buffer
- * \return the size
- */
-INLINE size_t
-ldns_buffer_limit(ldns_buffer *buffer)
-{
-	return buffer->_limit;
-}
-
-/**
- * changes the buffer's limit.  If the buffer's position is greater
- * than the new limit the position is set to the limit.
- * \param[in] buffer the buffer
- * \param[in] limit the new limit
- */
-INLINE void
-ldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
-{
-	assert(limit <= buffer->_capacity);
-	buffer->_limit = limit;
-	if (buffer->_position > buffer->_limit)
-		buffer->_position = buffer->_limit;
-}
-
-/**
- * returns the number of bytes the buffer can hold.
- * \param[in] buffer the buffer
- * \return the number of bytes
- */
-INLINE size_t
-ldns_buffer_capacity(ldns_buffer *buffer)
-{
-	return buffer->_capacity;
-}
-
-/**
- * changes the buffer's capacity.  The data is reallocated so any
- * pointers to the data may become invalid.  The buffer's limit is set
- * to the buffer's new capacity.
- * \param[in] buffer the buffer
- * \param[in] capacity the capacity to use
- * \return whether this failed or succeeded
- */
-bool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
-
-/**
- * ensures BUFFER can contain at least AMOUNT more bytes.  The buffer's
- * capacity is increased if necessary using buffer_set_capacity().
- *
- * The buffer's limit is always set to the (possibly increased)
- * capacity.
- * \param[in] buffer the buffer
- * \param[in] amount amount to use
- * \return whether this failed or succeeded
- */
-bool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
-
-/**
- * returns a pointer to the data at the indicated position.
- * \param[in] buffer the buffer
- * \param[in] at position
- * \return the pointer to the data
- */
-INLINE uint8_t *
-ldns_buffer_at(const ldns_buffer *buffer, size_t at)
-{
-	assert(at <= buffer->_limit);
-	return buffer->_data + at;
-}
-
-/**
- * returns a pointer to the beginning of the buffer (the data at
- * position 0).
- * \param[in] buffer the buffer
- * \return the pointer
- */
-INLINE uint8_t *
-ldns_buffer_begin(const ldns_buffer *buffer)
-{
-	return ldns_buffer_at(buffer, 0);
-}
-
-/**
- * returns a pointer to the end of the buffer (the data at the buffer's
- * limit).
- * \param[in] buffer the buffer
- * \return the pointer
- */
-INLINE uint8_t *
-ldns_buffer_end(ldns_buffer *buffer)
-{
-	return ldns_buffer_at(buffer, buffer->_limit);
-}
-
-/**
- * returns a pointer to the data at the buffer's current position.
- * \param[in] buffer the buffer
- * \return the pointer
- */
-INLINE uint8_t *
-ldns_buffer_current(ldns_buffer *buffer)
-{
-	return ldns_buffer_at(buffer, buffer->_position);
-}
-
-/**
- * returns the number of bytes remaining between the indicated position and
- * the limit.
- * \param[in] buffer the buffer
- * \param[in] at indicated position
- * \return number of bytes
- */
-INLINE size_t
-ldns_buffer_remaining_at(ldns_buffer *buffer, size_t at)
-{
-	ldns_buffer_invariant(buffer);
-	assert(at <= buffer->_limit);
-	return buffer->_limit - at;
-}
-
-/**
- * returns the number of bytes remaining between the buffer's position and
- * limit.
- * \param[in] buffer the buffer
- * \return the number of bytes
- */
-INLINE size_t
-ldns_buffer_remaining(ldns_buffer *buffer)
-{
-	return ldns_buffer_remaining_at(buffer, buffer->_position);
-}
-
-/**
- * checks if the buffer has at least COUNT more bytes available.
- * Before reading or writing the caller needs to ensure enough space
- * is available!
- * \param[in] buffer the buffer
- * \param[in] at indicated position
- * \param[in] count how much is available
- * \return true or false (as int?)
- */
-INLINE int
-ldns_buffer_available_at(ldns_buffer *buffer, size_t at, size_t count)
-{
-	return count <= ldns_buffer_remaining_at(buffer, at);
-}
-
-/**
- * checks if the buffer has count bytes available at the current position
- * \param[in] buffer the buffer
- * \param[in] count how much is available
- * \return true or false (as int?)
- */
-INLINE int
-ldns_buffer_available(ldns_buffer *buffer, size_t count)
-{
-	return ldns_buffer_available_at(buffer, buffer->_position, count);
-}
-
-/**
- * writes the given data to the buffer at the specified position
- * \param[in] buffer the buffer
- * \param[in] at the position (in number of bytes) to write the data at
- * \param[in] data pointer to the data to write to the buffer
- * \param[in] count the number of bytes of data to write
- */
-INLINE void
-ldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
-{
-	assert(ldns_buffer_available_at(buffer, at, count));
-	memcpy(buffer->_data + at, data, count);
-}
-
-/**
- * writes count bytes of data to the current position of the buffer
- * \param[in] buffer the buffer
- * \param[in] data the data to write
- * \param[in] count the lenght of the data to write
- */
-INLINE void
-ldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
-{
-	ldns_buffer_write_at(buffer, buffer->_position, data, count);
-	buffer->_position += count;
-}
-
-/**
- * copies the given (null-delimited) string to the specified position at the buffer
- * \param[in] buffer the buffer
- * \param[in] at the position in the buffer
- * \param[in] str the string to write
- */
-INLINE void
-ldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
-{
-	ldns_buffer_write_at(buffer, at, str, strlen(str));
-}
-
-/**
- * copies the given (null-delimited) string to the current position at the buffer
- * \param[in] buffer the buffer
- * \param[in] str the string to write
- */
-INLINE void
-ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
-{
-	ldns_buffer_write(buffer, str, strlen(str));
-}
-
-/**
- * writes the given byte of data at the given position in the buffer
- * \param[in] buffer the buffer
- * \param[in] at the position in the buffer
- * \param[in] data the 8 bits to write
- */
-INLINE void
-ldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
-{
-	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
-	buffer->_data[at] = data;
-}
-
-/**
- * writes the given byte of data at the current position in the buffer
- * \param[in] buffer the buffer
- * \param[in] data the 8 bits to write
- */
-INLINE void
-ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
-{
-	ldns_buffer_write_u8_at(buffer, buffer->_position, data);
-	buffer->_position += sizeof(data);
-}
-
-/**
- * writes the given 2 byte integer at the given position in the buffer
- * \param[in] buffer the buffer
- * \param[in] at the position in the buffer
- * \param[in] data the 16 bits to write
- */
-INLINE void
-ldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
-{
-	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
-	ldns_write_uint16(buffer->_data + at, data);
-}
-
-/**
- * writes the given 2 byte integer at the current position in the buffer
- * \param[in] buffer the buffer
- * \param[in] data the 16 bits to write
- */
-INLINE void
-ldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
-{
-	ldns_buffer_write_u16_at(buffer, buffer->_position, data);
-	buffer->_position += sizeof(data);
-}
-
-/**
- * writes the given 4 byte integer at the given position in the buffer
- * \param[in] buffer the buffer
- * \param[in] at the position in the buffer
- * \param[in] data the 32 bits to write
- */
-INLINE void
-ldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
-{
-	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
-	ldns_write_uint32(buffer->_data + at, data);
-}
-
-/**
- * writes the given 4 byte integer at the current position in the buffer
- * \param[in] buffer the buffer
- * \param[in] data the 32 bits to write
- */
-INLINE void
-ldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
-{
-	ldns_buffer_write_u32_at(buffer, buffer->_position, data);
-	buffer->_position += sizeof(data);
-}
-
-/**
- * copies count bytes of data at the given position to the given data-array
- * \param[in] buffer the buffer
- * \param[in] at the position in the buffer to start
- * \param[out] data buffer to copy to
- * \param[in] count the length of the data to copy
- */
-INLINE void
-ldns_buffer_read_at(ldns_buffer *buffer, size_t at, void *data, size_t count)
-{
-	assert(ldns_buffer_available_at(buffer, at, count));
-	memcpy(data, buffer->_data + at, count);
-}
-
-/**
- * copies count bytes of data at the current position to the given data-array
- * \param[in] buffer the buffer
- * \param[out] data buffer to copy to
- * \param[in] count the length of the data to copy
- */
-INLINE void
-ldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
-{
-	ldns_buffer_read_at(buffer, buffer->_position, data, count);
-	buffer->_position += count;
-}
-
-/**
- * returns the byte value at the given position in the buffer
- * \param[in] buffer the buffer
- * \param[in] at the position in the buffer
- * \return 1 byte integer
- */
-INLINE uint8_t
-ldns_buffer_read_u8_at(ldns_buffer *buffer, size_t at)
-{
-	assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
-	return buffer->_data[at];
-}
-
-/**
- * returns the byte value at the current position in the buffer
- * \param[in] buffer the buffer
- * \return 1 byte integer
- */
-INLINE uint8_t
-ldns_buffer_read_u8(ldns_buffer *buffer)
-{
-	uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
-	buffer->_position += sizeof(uint8_t);
-	return result;
-}
-
-/**
- * returns the 2-byte integer value at the given position in the buffer
- * \param[in] buffer the buffer
- * \param[in] at position in the buffer
- * \return 2 byte integer
- */
-INLINE uint16_t
-ldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
-{
-	assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
-	return ldns_read_uint16(buffer->_data + at);
-}
-
-/**
- * returns the 2-byte integer value at the current position in the buffer
- * \param[in] buffer the buffer
- * \return 2 byte integer
- */
-INLINE uint16_t
-ldns_buffer_read_u16(ldns_buffer *buffer)
-{
-	uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
-	buffer->_position += sizeof(uint16_t);
-	return result;
-}
-
-/**
- * returns the 4-byte integer value at the given position in the buffer
- * \param[in] buffer the buffer
- * \param[in] at position in the buffer
- * \return 4 byte integer
- */
-INLINE uint32_t
-ldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
-{
-	assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
-	return ldns_read_uint32(buffer->_data + at);
-}
-
-/**
- * returns the 4-byte integer value at the current position in the buffer
- * \param[in] buffer the buffer
- * \return 4 byte integer
- */
-INLINE uint32_t
-ldns_buffer_read_u32(ldns_buffer *buffer)
-{
-	uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
-	buffer->_position += sizeof(uint32_t);
-	return result;
-}
-
-/**
- * returns the status of the buffer
- * \param[in] buffer
- * \return the status
- */
-INLINE ldns_status
-ldns_buffer_status(ldns_buffer *buffer)
-{
-	return buffer->_status;
-}
-
-/**
- * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
- * \param[in] buffer the buffer
- * \return true or false
- */
-INLINE bool
-ldns_buffer_status_ok(ldns_buffer *buffer)
-{
-	if (buffer) {
-		return ldns_buffer_status(buffer) == LDNS_STATUS_OK;
-	} else {
-		return false;
-	}
-}
-
-/**
- * prints to the buffer, increasing the capacity if required using
- * buffer_reserve(). The buffer's position is set to the terminating '\\0'
- * Returns the number of characters written (not including the
- * terminating '\\0') or -1 on failure.
- */
-int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
-/*	ATTR_FORMAT(printf, 2, 3);*/
-
-/**
- * frees the buffer.
- * \param[in] *buffer the buffer to be freed
- * \return void
- */
-void ldns_buffer_free(ldns_buffer *buffer);
-
-/**
- * Makes the buffer fixed and returns a pointer to the data.  The
- * caller is responsible for free'ing the result.
- * \param[in] *buffer the buffer to be exported
- * \return void
- */
-void *ldns_buffer_export(ldns_buffer *buffer);
-
-/**
- * Copy contents of the from buffer to the result buffer and then flips 
- * the result buffer. Data will be silently truncated if the result buffer is
- * too small.
- * \param[out] *result resulting buffer which is copied to.
- * \param[in] *from what to copy to result.
- */
-void ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_BUFFER_H */
diff --git a/include/ldns/common.h b/include/ldns/common.h
deleted file mode 100644
index 9abd9b9..0000000
--- a/include/ldns/common.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * \file common.h
- *
- * Common definitions for LDNS
- */
-
-/**
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#ifndef LDNS_COMMON_H
-#define LDNS_COMMON_H
-
-/*
- * The build configuration that is used in the distributed headers,
- * as detected and determined by the auto configure script.
- */
-#define LDNS_BUILD_CONFIG_HAVE_SSL         1
-#define LDNS_BUILD_CONFIG_HAVE_INTTYPES_H  1
-#define LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT 1
-#define LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED 1
-#define LDNS_BUILD_CONFIG_HAVE_SOCKLEN_T   1
-#define LDNS_BUILD_CONFIG_USE_DANE         1
-#define LDNS_BUILD_CONFIG_HAVE_B32_PTON    0
-#define LDNS_BUILD_CONFIG_HAVE_B32_NTOP    0
-
-/*
- * HAVE_STDBOOL_H is not available when distributed as a library, but no build 
- * configuration variables may be used (like those above) because the header
- * is sometimes only available when using special compiler flags to enable the
- * c99 environment. Because we cannot force the usage of this flag, we have to
- * provide a default type. Below what is suggested by the autoconf manual.
- */
-/*@ignore@*/
-/* splint barfs on this construct */
-#ifndef __bool_true_false_are_defined
-# ifdef HAVE_STDBOOL_H
-#  include <stdbool.h>
-# else
-#  ifndef HAVE__BOOL
-#   ifdef __cplusplus
-typedef bool _Bool;
-#   else
-#    define _Bool signed char
-#   endif
-#  endif
-#  define bool _Bool
-#  define false 0
-#  define true 1
-#  define __bool_true_false_are_defined 1
-# endif
-#endif
-/*@end@*/
-
-#if LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT
-#define ATTR_FORMAT(archetype, string_index, first_to_check) \
-    __attribute__ ((format (archetype, string_index, first_to_check)))
-#else /* !LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT */
-#define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
-#endif /* !LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT */
-
-#if defined(__cplusplus)
-#define ATTR_UNUSED(x)
-#elif LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED
-#define ATTR_UNUSED(x)  x __attribute__((unused))
-#else /* !LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED */
-#define ATTR_UNUSED(x)  x
-#endif /* !LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED */
-
-#if !LDNS_BUILD_CONFIG_HAVE_SOCKLEN_T
-typedef int socklen_t;
-#endif
-
-#endif /* LDNS_COMMON_H */
diff --git a/include/ldns/config.h b/include/ldns/config.h
deleted file mode 100644
index d77cc7f..0000000
--- a/include/ldns/config.h
+++ /dev/null
@@ -1,590 +0,0 @@
-#include "EXTERN.h"
-#include "perl.h"
-
-/* Define if building universal (internal helper macro) */
-/* #undef AC_APPLE_UNIVERSAL_BUILD */
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#define HAVE_ARPA_INET_H 1
-
-/* Whether the C compiler accepts the "format" attribute */
-#define HAVE_ATTR_FORMAT 1
-
-/* Whether the C compiler accepts the "unused" attribute */
-#define HAVE_ATTR_UNUSED 1
-
-/* Define to 1 if you have the `b32_ntop' function. */
-/* #undef HAVE_B32_NTOP */
-
-/* Define to 1 if you have the `b32_pton' function. */
-/* #undef HAVE_B32_PTON */
-
-/* Define to 1 if you have the `b64_ntop' function. */
-/* #undef HAVE_B64_NTOP */
-
-/* Define to 1 if you have the `b64_pton' function. */
-/* #undef HAVE_B64_PTON */
-
-/* Define to 1 if you have the `bzero' function. */
-#define HAVE_BZERO 1
-
-/* Define to 1 if you have the `calloc' function. */
-#define HAVE_CALLOC 1
-
-/* Define to 1 if you have the `ctime_r' function. */
-#define HAVE_CTIME_R 1
-
-/* Is a CAFILE given at configure time */
-#define HAVE_DANE_CA_FILE 0
-
-/* Is a CAPATH given at configure time */
-#define HAVE_DANE_CA_PATH 0
-
-/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
-   don't. */
-#define HAVE_DECL_NID_SECP384R1 1
-
-/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0
-   if you don't. */
-#define HAVE_DECL_NID_X9_62_PRIME256V1 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the `endprotoent' function. */
-#define HAVE_ENDPROTOENT 1
-
-/* Define to 1 if you have the `endservent' function. */
-#define HAVE_ENDSERVENT 1
-
-/* Define to 1 if you have the `ENGINE_load_cryptodev' function. */
-#define HAVE_ENGINE_LOAD_CRYPTODEV 1
-
-/* Define to 1 if you have the `EVP_sha256' function. */
-#define HAVE_EVP_SHA256 1
-
-/* Define to 1 if you have the `fcntl' function. */
-#define HAVE_FCNTL 1
-
-/* Define to 1 if you have the `fork' function. */
-#define HAVE_FORK 1
-
-/* Whether getaddrinfo is available */
-#define HAVE_GETADDRINFO 1
-
-/* Define to 1 if you have the <getopt.h> header file. */
-#define HAVE_GETOPT_H 1
-
-/* Define to 1 if you have the `gmtime_r' function. */
-#define HAVE_GMTIME_R 1
-
-/* If you have HMAC_CTX_init */
-#define HAVE_HMAC_CTX_INIT 1
-
-/* Define to 1 if you have the `inet_aton' function. */
-#define HAVE_INET_ATON 1
-
-/* Define to 1 if you have the `inet_ntop' function. */
-#define HAVE_INET_NTOP 1
-
-/* Define to 1 if you have the `inet_pton' function. */
-#define HAVE_INET_PTON 1
-
-/* define if you have inttypes.h */
-#define HAVE_INTTYPES_H 1
-
-/* if the function 'ioctlsocket' is available */
-/* #undef HAVE_IOCTLSOCKET */
-
-/* Define to 1 if you have the `isascii' function. */
-#define HAVE_ISASCII 1
-
-/* Define to 1 if you have the `isblank' function. */
-#define HAVE_ISBLANK 1
-
-/* Define to 1 if you have the `pcap' library (-lpcap). */
-/* #undef HAVE_LIBPCAP */
-
-/* Define to 1 if you have the `localtime_r' function. */
-#define HAVE_LOCALTIME_R 1
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
-   to 0 otherwise. */
-#define HAVE_MALLOC 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `memset' function. */
-#define HAVE_MEMSET 1
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/if_ether.h> header file. */
-/* #undef HAVE_NETINET_IF_ETHER_H */
-
-/* Define to 1 if you have the <netinet/igmp.h> header file. */
-/* #undef HAVE_NETINET_IGMP_H */
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the <netinet/in_systm.h> header file. */
-/* #undef HAVE_NETINET_IN_SYSTM_H */
-
-/* Define to 1 if you have the <netinet/ip6.h> header file. */
-/* #undef HAVE_NETINET_IP6_H */
-
-/* Define to 1 if you have the <netinet/ip_compat.h> header file. */
-/* #undef HAVE_NETINET_IP_COMPAT_H */
-
-/* Define to 1 if you have the <netinet/ip.h> header file. */
-/* #undef HAVE_NETINET_IP_H */
-
-/* Define to 1 if you have the <netinet/udp.h> header file. */
-/* #undef HAVE_NETINET_UDP_H */
-
-/* Define to 1 if you have the <net/ethernet.h> header file. */
-/* #undef HAVE_NET_ETHERNET_H */
-
-/* Define to 1 if you have the <net/if.h> header file. */
-/* #undef HAVE_NET_IF_H */
-
-/* Define to 1 if you have the <openssl/err.h> header file. */
-#define HAVE_OPENSSL_ERR_H 1
-
-/* Define to 1 if you have the <openssl/rand.h> header file. */
-#define HAVE_OPENSSL_RAND_H 1
-
-/* Define to 1 if you have the <openssl/ssl.h> header file. */
-#define HAVE_OPENSSL_SSL_H 1
-
-/* Define to 1 if you have the <pcap.h> header file. */
-/* #undef HAVE_PCAP_H */
-
-/* Define to 1 if you have the `random' function. */
-#define HAVE_RANDOM 1
-
-/* Define to 1 if your system has a GNU libc compatible `realloc' function,
-   and to 0 otherwise. */
-#define HAVE_REALLOC 1
-
-/* Define to 1 if you have the `sleep' function. */
-#define HAVE_SLEEP 1
-
-/* Define to 1 if you have the `snprintf' function. */
-#define HAVE_SNPRINTF 1
-
-/* Define if you have the SSL libraries installed. */
-#define HAVE_SSL /**/
-
-/* Define to 1 if you have the <stdarg.h> header file. */
-#define HAVE_STDARG_H 1
-
-/* Define to 1 if stdbool.h conforms to C99. */
-#define HAVE_STDBOOL_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strlcpy' function. */
-#ifdef HAS_STRLCPY
-#define HAVE_STRLCPY 1
-#else
-#undef HAVE_STRLCPY
-#endif
-
-/* Define to 1 if you have the `strtoul' function. */
-#define HAVE_STRTOUL 1
-
-/* Define to 1 if you have the <sys/mount.h> header file. */
-#define HAVE_SYS_MOUNT_H 1
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* define if you have sys/socket.h */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* define if you have sys/types.h */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the `timegm' function. */
-#define HAVE_TIMEGM 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* define if you have unistd.h */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if you have the `vfork' function. */
-#define HAVE_VFORK 1
-
-/* Define to 1 if you have the <vfork.h> header file. */
-/* #undef HAVE_VFORK_H */
-
-/* Define to 1 if you have the <winsock2.h> header file. */
-/* #undef HAVE_WINSOCK2_H */
-
-/* Define to 1 if `fork' works. */
-#define HAVE_WORKING_FORK 1
-
-/* Define to 1 if `vfork' works. */
-#define HAVE_WORKING_VFORK 1
-
-/* Define to 1 if you have the <ws2tcpip.h> header file. */
-/* #undef HAVE_WS2TCPIP_H */
-
-/* Define to 1 if the system has the type `_Bool'. */
-#define HAVE__BOOL 1
-
-/* Is a CAFILE given at configure time */
-/* #undef LDNS_DANE_CA_FILE */
-
-/* Is a CAPATH given at configure time */
-/* #undef LDNS_DANE_CA_PATH */
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "libdns@nlnetlabs.nl"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "ldns"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "ldns 1.6.17"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "libdns"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.6.17"
-
-/* Define this to enable RR type NINFO. */
-/* #undef RRTYPE_NINFO */
-
-/* Define this to enable RR type OPENPGPKEY. */
-/* #undef RRTYPE_OPENPGPKEY */
-
-/* Define this to enable RR type RKEY. */
-/* #undef RRTYPE_RKEY */
-
-/* Define this to enable RR type TA. */
-/* #undef RRTYPE_TA */
-
-/* Define this to enable RR type URI. */
-/* #undef RRTYPE_URI */
-
-/* The size of `time_t', as computed by sizeof. */
-#define SIZEOF_TIME_T 8
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define this to enable messages to stderr. */
-/* #undef STDERR_MSGS */
-
-/* System configuration dir */
-#define SYSCONFDIR sysconfdir
-
-/* Define this to enable DANE support. */
-#define USE_DANE 1
-
-/* Define this to enable ECDSA support. */
-#define USE_ECDSA 1
-
-/* Define this to enable GOST support. */
-/* #define USE_GOST 1 */
-
-/* Define this to enable SHA256 and SHA512 support. */
-#define USE_SHA2 1
-
-/* Enable extensions on AIX 3, Interix.  */
-#ifndef _ALL_SOURCE
-# define _ALL_SOURCE 1
-#endif
-/* Enable GNU extensions on systems that have them.  */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-/* Enable threading extensions on Solaris.  */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# define _POSIX_PTHREAD_SEMANTICS 1
-#endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# define _TANDEM_SOURCE 1
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-
-/* Whether the windows socket API is used */
-/* #undef USE_WINSOCK */
-
-/* the version of the windows API enabled */
-#define WINVER 0x0502
-
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
-   significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-#  define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-/* #  undef WORDS_BIGENDIAN */
-# endif
-#endif
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Enable for compile on Minix */
-/* #undef _NETBSD_SOURCE */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* in_addr_t */
-/* #undef in_addr_t */
-
-/* in_port_t */
-/* #undef in_port_t */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
-   calls it, or to nothing if 'inline' is not supported under any name.  */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to `short' if <sys/types.h> does not define. */
-/* #undef int16_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef int32_t */
-
-/* Define to `long long' if <sys/types.h> does not define. */
-/* #undef int64_t */
-
-/* Define to `char' if <sys/types.h> does not define. */
-/* #undef int8_t */
-
-/* Define to `size_t' if <sys/types.h> does not define. */
-/* #undef intptr_t */
-
-/* Define to rpl_malloc if the replacement function should be used. */
-/* #undef malloc */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef pid_t */
-
-/* Define to rpl_realloc if the replacement function should be used. */
-/* #undef realloc */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* Define to 'int' if not defined */
-/* #undef socklen_t */
-
-/* Fallback member name for socket family in struct sockaddr_storage */
-/* #undef ss_family */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef ssize_t */
-
-/* Define to `unsigned short' if <sys/types.h> does not define. */
-/* #undef uint16_t */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef uint32_t */
-
-/* Define to `unsigned long long' if <sys/types.h> does not define. */
-/* #undef uint64_t */
-
-/* Define to `unsigned char' if <sys/types.h> does not define. */
-/* #undef uint8_t */
-
-/* Define as `fork' if `vfork' does not work. */
-/* #undef vfork */
-
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
-
-#ifndef BYTE_ORDER
-#ifdef WORDS_BIGENDIAN
-#define BYTE_ORDER BIG_ENDIAN
-#else
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif /* WORDS_BIGENDIAN */
-#endif /* BYTE_ORDER */
-
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
-
-#ifdef HAVE_WS2TCPIP_H
-#include <ws2tcpip.h>
-#endif
-
-
-/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
-#ifdef HAVE_WINSOCK2_H
-#define FD_SET_T (u_int)
-#else
-#define FD_SET_T 
-#endif
-
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int ldns_b64_ntop(uint8_t const *src, size_t srclength,
-	 	  char *target, size_t targsize);
-/**
- * calculates the size needed to store the result of b64_ntop
- */
-/*@unused@*/
-static inline size_t ldns_b64_ntop_calculate_size(size_t srcsize)
-{
-	return ((((srcsize + 2) / 3) * 4) + 1);
-}
-int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
-/**
- * calculates the size needed to store the result of ldns_b64_pton
- */
-/*@unused@*/
-static inline size_t ldns_b64_pton_calculate_size(size_t srcsize)
-{
-	return (((((srcsize + 3) / 4) * 3)) + 1);
-}
-
-/**
- * Given in dnssec_zone.c, also used in dnssec_sign.c:w
-
- */
-int ldns_dname_compare_v(const void *a, const void *b);
-
-#ifndef HAVE_SLEEP
-/* use windows sleep, in millisecs, instead */
-#define sleep(x) Sleep((x)*1000)
-#endif
-
-#ifndef HAVE_RANDOM
-#define srandom(x) srand(x)
-#define random(x) rand(x)
-#endif
-
-#ifndef HAVE_TIMEGM
-#include <time.h>
-time_t timegm (struct tm *tm);
-#endif /* !TIMEGM */
-#ifndef HAVE_GMTIME_R
-struct tm *gmtime_r(const time_t *timep, struct tm *result);
-#endif
-#ifndef HAVE_LOCALTIME_R
-struct tm *localtime_r(const time_t *timep, struct tm *result);
-#endif
-#ifndef HAVE_ISBLANK
-int isblank(int c);
-#endif /* !HAVE_ISBLANK */
-#ifndef HAVE_ISASCII
-int isascii(int c);
-#endif /* !HAVE_ISASCII */
-#ifndef HAVE_SNPRINTF
-#include <stdarg.h>
-int snprintf (char *str, size_t count, const char *fmt, ...);
-int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-#endif /* HAVE_SNPRINTF */
-#ifndef HAVE_INET_PTON
-int inet_pton(int af, const char* src, void* dst);
-#endif /* HAVE_INET_PTON */
-#ifndef HAVE_INET_NTOP
-const char *inet_ntop(int af, const void *src, char *dst, size_t size);
-#endif
-#ifndef HAVE_INET_ATON
-int inet_aton(const char *cp, struct in_addr *addr);
-#endif
-#ifndef HAVE_MEMMOVE
-void *memmove(void *dest, const void *src, size_t n);
-#endif
-#ifndef HAVE_STRLCPY
-size_t strlcpy(char *dst, const char *src, size_t siz);
-#endif
-#ifdef __cplusplus
-}
-#endif
-#ifndef HAVE_GETADDRINFO
-#include "compat/fake-rfc2553.h"
-#endif
-#ifndef HAVE_STRTOUL
-#define strtoul (unsigned long)strtol
-#endif
-
diff --git a/include/ldns/dane.h b/include/ldns/dane.h
deleted file mode 100644
index 8234eb7..0000000
--- a/include/ldns/dane.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * dane.h -- defines for the DNS-Based Authentication of Named Entities (DANE)
- *                           Transport Layer Security (TLS) Protocol: TLSA
- *
- * Copyright (c) 2012, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- *
- */
-
-/**
- * \file
- *
- * This module contains base functions for creating and verifying TLSA RR's
- * with PKIX certificates, certificate chains and validation stores.
- * (See RFC6394 and RFC6698).
- * 
- * Since those functions heavily rely op cryptographic operations,
- * this module is dependent on openssl.
- */
- 
-
-#ifndef LDNS_DANE_H
-#define LDNS_DANE_H
-#if LDNS_BUILD_CONFIG_USE_DANE
-
-#include <ldns/common.h>
-#include <ldns/rdata.h>
-#include <ldns/rr.h>
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * The different "Certificate usage" rdata field values for a TLSA RR.
- */
-enum ldns_enum_tlsa_certificate_usage
-{
-	/** CA constraint */
-	LDNS_TLSA_USAGE_PKIX_TA				=   0,
-	LDNS_TLSA_USAGE_CA_CONSTRAINT			=   0,
-	/** Sevice certificate constraint */
-	LDNS_TLSA_USAGE_PKIX_EE				=   1,
-	LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT	=   1,
-	/** Trust anchor assertion */
-	LDNS_TLSA_USAGE_DANE_TA				=   2,
-	LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION		=   2,
-	/** Domain issued certificate */
-	LDNS_TLSA_USAGE_DANE_EE				=   3,
-	LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE	=   3,
-	/** Reserved for Private Use */
-	LDNS_TLSA_USAGE_PRIVCERT			= 255
-};
-typedef enum ldns_enum_tlsa_certificate_usage ldns_tlsa_certificate_usage;
-
-/**
- * The different "Selector" rdata field values for a TLSA RR.
- */
-enum ldns_enum_tlsa_selector
-{
-	/** 
-	 * Full certificate: the Certificate binary structure
-	 * as defined in [RFC5280]
-	 */
-	LDNS_TLSA_SELECTOR_CERT			=   0,
-	LDNS_TLSA_SELECTOR_FULL_CERTIFICATE	=   0,
-
-	/** 
-	 * SubjectPublicKeyInfo: DER-encoded binary structure
-	 * as defined in [RFC5280]
-	 */
-	LDNS_TLSA_SELECTOR_SPKI			=   1,
-	LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO	=   1,
-
-	/** Reserved for Private Use */
-	LDNS_TLSA_SELECTOR_PRIVSEL		= 255
-};
-typedef enum ldns_enum_tlsa_selector ldns_tlsa_selector;
-
-/**
- * The different "Matching type" rdata field values for a TLSA RR.
- */
-enum ldns_enum_tlsa_matching_type
-{
-	/** Exact match on selected content */
-	LDNS_TLSA_MATCHING_TYPE_FULL		=   0,
-	LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED	=   0,
-	/** SHA-256 hash of selected content [RFC6234] */
-	LDNS_TLSA_MATCHING_TYPE_SHA2_256	=   1,
-	LDNS_TLSA_MATCHING_TYPE_SHA256		=   1,
-	/** SHA-512 hash of selected content [RFC6234] */
-	LDNS_TLSA_MATCHING_TYPE_SHA2_512	=   2,
-	LDNS_TLSA_MATCHING_TYPE_SHA512		=   2,
-	/** Reserved for Private Use */
-	LDNS_TLSA_MATCHING_TYPE_PRIVMATCH	= 255
-};
-typedef enum ldns_enum_tlsa_matching_type ldns_tlsa_matching_type;
-
-/**
- * Known transports to use with TLSA owner names.
- */
-enum ldns_enum_dane_transport
-{
-	/** TCP */
-	LDNS_DANE_TRANSPORT_TCP  = 0,
-	/** UDP */
-	LDNS_DANE_TRANSPORT_UDP  = 1,
-	/** SCTP */
-	LDNS_DANE_TRANSPORT_SCTP = 2
-};
-typedef enum ldns_enum_dane_transport ldns_dane_transport;
-
-
-/**
- * Creates a dname consisting of the given name, prefixed by the service port
- * and type of transport: _<EM>port</EM>._<EM>transport</EM>.<EM>name</EM>.
- *
- * \param[out] tlsa_owner The created dname.
- * \param[in] name The dname that should be prefixed.
- * \param[in] port The service port number for wich the name should be created.
- * \param[in] transport The transport for wich the name should be created.
- * \return LDNS_STATUS_OK on success or an error code otherwise.
- */
-ldns_status ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner,
-		const ldns_rdf* name, uint16_t port,
-		ldns_dane_transport transport);
-
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * Creates a LDNS_RDF_TYPE_HEX type rdf based on the binary data choosen by
- * the selector and encoded using matching_type.
- *
- * \param[out] rdf The created created rdf of type LDNS_RDF_TYPE_HEX.
- * \param[in] cert The certificate from which the data is selected
- * \param[in] selector The full certificate or the public key
- * \param[in] matching_type The full data or the SHA256 or SHA512 hash
- *            of the selected data
- * \return LDNS_STATUS_OK on success or an error code otherwise.
- */
-ldns_status ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
-		ldns_tlsa_selector      selector,
-		ldns_tlsa_matching_type matching_type);
-
-
-/**
- * Selects the certificate from cert, extra_certs or the pkix_validation_store
- * based on the value of cert_usage and index.
- *
- * \param[out] selected_cert The selected cert.
- * \param[in] cert The certificate to validate (or not)
- * \param[in] extra_certs Intermediate certificates that might be necessary
- *            during validation. May be NULL, except when the certificate 
- *            usage is "Trust Anchor Assertion" because the trust anchor has
- *            to be provided.(otherwise choose a "Domain issued certificate!"
- * \param[in] pkix_validation_store Used when the certificate usage is 
- *            "CA constraint" or "Service Certificate Constraint" to 
- *            validate the certificate and, in case of "CA constraint",
- *            select the CA.
- *            When pkix_validation_store is NULL, validation is explicitely
- *            turned off and the behaviour is then the same as for "Trust
- *            anchor assertion" and "Domain issued certificate" respectively.
- * \param[in] cert_usage Which certificate to use and how to validate.
- * \param[in] index Used to select the trust anchor when certificate usage
- *            is "Trust Anchor Assertion". 0 is the last certificate in the
- *            validation chain. 1 the one but last, etc. When index is -1,
- *            the last certificate is used that MUST be self-signed.
- *            This can help to make sure that the intended (self signed)
- *            trust anchor is actually present in extra_certs (which is a
- *            DANE requirement).
- *
- * \return LDNS_STATUS_OK on success or an error code otherwise.
- */
-ldns_status ldns_dane_select_certificate(X509** selected_cert,
-		X509* cert, STACK_OF(X509)* extra_certs,
-		X509_STORE* pkix_validation_store,
-		ldns_tlsa_certificate_usage cert_usage, int index);
-
-/**
- * Creates a TLSA resource record from the certificate.
- * No PKIX validation is performed! The given certificate is used as data
- * regardless the value of certificate_usage.
- *
- * \param[out] tlsa The created TLSA resource record.
- * \param[in] certificate_usage The value for the Certificate Usage field
- * \param[in] selector The value for the Selector field
- * \param[in] matching_type The value for the Matching Type field
- * \param[in] cert The certificate which data will be represented
- *
- * \return LDNS_STATUS_OK on success or an error code otherwise.
- */
-ldns_status ldns_dane_create_tlsa_rr(ldns_rr** tlsa,
-		ldns_tlsa_certificate_usage certificate_usage,
-		ldns_tlsa_selector          selector,
-		ldns_tlsa_matching_type     matching_type,
-		X509* cert);
-
-/**
- * Verify if the given TLSA resource record matches the given certificate.
- * Reporting on a TLSA rr mismatch (LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH)
- * is preferred over PKIX failure  (LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE).
- * So when PKIX validation is required by the TLSA Certificate usage,
- * but the TLSA data does not match, LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH
- * is returned whether the PKIX validated or not.
- *
- * \param[in] tlsa_rr The resource record that specifies what and how to
- *            match the certificate. With tlsa_rr == NULL, regular PKIX
- *            validation is performed.
- * \param[in] cert The certificate to match (and validate)
- * \param[in] extra_certs Intermediate certificates that might be necessary
- *            creating the validation chain.
- * \param[in] pkix_validation_store Used when the certificate usage is 
- *            "CA constraint" or "Service Certificate Constraint" to 
- *            validate the certificate.
- *
- * \return LDNS_STATUS_OK on success,
- *         LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH on TLSA data mismatch,
- *         LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE when TLSA matched,
- *         but the PKIX validation failed, or other ldns_status errors.
- */
-ldns_status ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
-		X509* cert, STACK_OF(X509)* extra_certs,
-		X509_STORE* pkix_validation_store);
-
-/**
- * Verify if any of the given TLSA resource records matches the given
- * certificate.
- *
- * \param[in] tlsas The resource records that specify what and how to
- *            match the certificate. One must match for this function
- *            to succeed. With tlsas == NULL or the number of TLSA records
- *            in tlsas == 0, regular PKIX validation is performed.
- * \param[in] cert The certificate to match (and validate)
- * \param[in] extra_certs Intermediate certificates that might be necessary
- *            creating the validation chain.
- * \param[in] pkix_validation_store Used when the certificate usage is 
- *            "CA constraint" or "Service Certificate Constraint" to 
- *            validate the certificate.
- *
- * \return LDNS_STATUS_OK on success,
- *         LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE when one of the TLSA's
- *         matched but the PKIX validation failed,
- *         LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH when none of the TLSA's matched,
- *         or other ldns_status errors.
- */
-ldns_status ldns_dane_verify(ldns_rr_list* tlsas,
-		X509* cert, STACK_OF(X509)* extra_certs,
-		X509_STORE* pkix_validation_store);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_BUILD_CONFIG_USE_DANE */
-#endif /* LDNS_DANE_H */
-
diff --git a/include/ldns/dname.h b/include/ldns/dname.h
deleted file mode 100644
index 291786b..0000000
--- a/include/ldns/dname.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * dname.h
- *
- * dname definitions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file dname.h
- *
- * dname contains function to read and manipulate domain names.
- *
- * Example domain names are "www.nlnetlabs.nl." and "." (the root)
- *
- * If a domain name ends with a dot ("."), it is called a Fully Qualified
- * Domain Name (FQDN). In certain places (for instance when reading a zone
- * file), an origin (which is just another domain name) non-FQDNs will be
- * placed after the current. For instance, if i have a zone file where the
- * origin has been set to "nl.", and my file contains the name
- * "www.nlnetlabs", it will result in "www.nlnetlabs.nl.". Internally, dnames are
- * always absolute (the dot is added when it is missing and there is no origin).
- *
- * An FQDN is also
- * known as an absolute domain name, therefore the function to check this is
- * called \ref ldns_dname_str_absolute
- *
- * Domain names are stored in \ref ldns_rdf structures, with the type
- * \ref LDNS_RDF_TYPE_DNAME
- *
- * This module is *NOT* about the RR type called DNAME.
- */
-
-
-#ifndef LDNS_DNAME_H
-#define LDNS_DNAME_H
-
-#include <ldns/common.h>
-#include <ldns/rdata.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LDNS_DNAME_NORMALIZE        tolower
-
-/**
- * concatenates two dnames together
- * \param[in] rd1 the leftside
- * \param[in] rd2 the rightside
- * \return a new rdf with leftside/rightside
- */
-ldns_rdf *ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2);
-
-/**
- * concatenates rd2 after rd1 (rd2 is copied, rd1 is modified)
- * \param[in] rd1 the leftside
- * \param[in] rd2 the rightside
- * \return LDNS_STATUS_OK on success
- */
-ldns_status 	ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2);
-
-/**
- * Returns a clone of the given dname with the labels
- * reversed
- * \param[in] d the dname to reverse
- * \return clone of the dname with the labels reversed.
- */
-ldns_rdf *ldns_dname_reverse(const ldns_rdf *d);
-
-/**
- * Clones the given dname from the nth label on
- * \param[in] d The dname to clone
- * \param[in] n the label nr to clone from, if this is 0, the complete
- *              dname is cloned
- * \return A newly allocated *rdf structure, containing the cloned dname,
- *         or NULL if either d was NULL, not a dname, or if n >=
- *         label_count
- */
-ldns_rdf *
-ldns_dname_clone_from(const ldns_rdf *d, uint16_t n);
-
-/**
- * chop one label off the left side of a dname. so
- * wwww.nlnetlabs.nl, becomes nlnetlabs.nl
- * This new name is a clone and must be freed with ldns_deep_free()
- * \param[in] d the dname to chop
- * \return the remaining dname
- */
-ldns_rdf *ldns_dname_left_chop(const ldns_rdf *d);
-
-/**
- * count the number of labels inside a LDNS_RDF_DNAME type rdf.
- * \param[in] *r the rdf
- * \return the number of labels
- */
-uint8_t  ldns_dname_label_count(const ldns_rdf *r);
-
-/**
- * creates a new dname rdf from a string.
- * \param[in] str string to use
- * \return ldns_rdf* or NULL in case of an error
- */
-ldns_rdf *ldns_dname_new_frm_str(const char *str);
-
-/**
- * Create a new dname rdf from a string
- * \param[in] s the size of the new dname
- * \param[in] *data pointer to the actual data
- *
- * \return ldns_rdf*
- */
-ldns_rdf *ldns_dname_new(uint16_t s, void *data);
-
-/**
- * Create a new dname rdf from data (the data is copied)
- * \param[in] size the size of the data
- * \param[in] *data pointer to the actual data
- *
- * \return ldns_rdf*
- */
-ldns_rdf *ldns_dname_new_frm_data(uint16_t size, const void *data);
-
-/**
- * Put a dname into canonical fmt - ie. lowercase it
- * \param[in] rdf the dname to lowercase
- * \return void
- */
-void ldns_dname2canonical(const ldns_rdf *rdf);
-
-/**
- * test wether the name sub falls under parent (i.e. is a subdomain
- * of parent). This function will return false if the given dnames are
- * equal.
- * \param[in] sub the name to test
- * \param[in] parent the parent's name
- * \return true if sub falls under parent, otherwise false
- */
-bool ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent);
-
-/**
- * Compares the two dname rdf's according to the algorithm for ordering
- * in RFC4034 Section 6.
- * \param[in] dname1 First dname rdf to compare
- * \param[in] dname2 Second dname rdf to compare
- * \return -1 if dname1 comes before dname2, 1 if dname1 comes after dname2, and 0 if they are equal.
- */
-int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2);
-int ldns_dname_compare_v(const void *, const void *);
-
-/**
- * Checks whether the dname matches the given wildcard
- * \param[in] dname The dname to check
- * \param[in] wildcard The wildcard to check with
- * \return 1 If the wildcard matches, OR if 'wildcard' is not a wildcard and
- *           the names are *exactly* the same
- *         0 If the wildcard does not match, or if it is not a wildcard and
- *           the names are not the same
- */
-int ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard);
-
-/**
- * check if middle lays in the interval defined by prev and next
- * prev <= middle < next. This is usefull for nsec checking
- * \param[in] prev the previous dname
- * \param[in] middle the dname to check
- * \param[in] next the next dname
- * return 0 on error or unknown, -1 when middle is in the interval, +1 when not
- */
-int ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle, const ldns_rdf *next);
-
-/**
- * Checks whether the given dname string is absolute (i.e. ends with a '.')
- * \param[in] *dname_str a string representing the dname
- * \return true or false
- */
-bool ldns_dname_str_absolute(const char *dname_str);
-
-/**
- * Checks whether the given dname is absolute (i.e. ends with a '.')
- * \param[in] *dname a rdf representing the dname
- * \return true or false
- */
-bool ldns_dname_absolute(const ldns_rdf *dname);
-
-/**
- * look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME
- * try and retrieve a specific label. The labels are numbered
- * starting from 0 (left most).
- * \param[in] rdf the rdf to look in
- * \param[in] labelpos return the label with this number
- * \return a ldns_rdf* with the label as name or NULL on error
- */
-ldns_rdf * ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos);
-
-/**
- * Check if dname is a wildcard, starts with *.
- * \param[in] dname: the rdf to look in
- * \return true if a wildcard, false if not.
- */
-int ldns_dname_is_wildcard(const ldns_rdf* dname);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif	/* LDNS_DNAME_H */
diff --git a/include/ldns/dnssec.h b/include/ldns/dnssec.h
deleted file mode 100644
index f4cdafb..0000000
--- a/include/ldns/dnssec.h
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * dnssec.h -- defines for the Domain Name System (SEC) (DNSSEC)
- *
- * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- *
- * A bunch of defines that are used in the DNS
- */
-
-/**
- * \file dnssec.h
- *
- * This module contains base functions for DNSSEC operations
- * (RFC4033 t/m RFC4035).
- * 
- * Since those functions heavily rely op cryptographic operations,
- * this module is dependent on openssl.
- * 
- */
- 
-
-#ifndef LDNS_DNSSEC_H
-#define LDNS_DNSSEC_H
-
-#include <ldns/common.h>
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-#include <openssl/ssl.h>
-#include <openssl/evp.h>
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-#include <ldns/packet.h>
-#include <ldns/keys.h>
-#include <ldns/zone.h>
-#include <ldns/resolver.h>
-#include <ldns/dnssec_zone.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LDNS_MAX_KEYLEN		2048
-#define LDNS_DNSSEC_KEYPROTO	3
-/* default time before sigs expire */
-#define LDNS_DEFAULT_EXP_TIME	2419200 /* 4 weeks */
-
-/** return values for the old-signature callback */
-#define LDNS_SIGNATURE_LEAVE_ADD_NEW 0
-#define LDNS_SIGNATURE_LEAVE_NO_ADD 1
-#define LDNS_SIGNATURE_REMOVE_ADD_NEW 2
-#define LDNS_SIGNATURE_REMOVE_NO_ADD 3
-
-/**
- * Returns the first RRSIG rr that corresponds to the rrset 
- * with the given name and type
- * 
- * \param[in] name The dname of the RRset covered by the RRSIG to find
- * \param[in] type The type of the RRset covered by the RRSIG to find
- * \param[in] rrs List of rrs to search in
- * \returns Pointer to the first RRsig ldns_rr found, or NULL if it is
- * not present
- */
-ldns_rr *ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name,
-									    const ldns_rr_type type,
-									    const ldns_rr_list *rrs);
-
-/**
- * Returns the DNSKEY that corresponds to the given RRSIG rr from the list, if
- * any
- *
- * \param[in] rrsig The rrsig to find the DNSKEY for
- * \param[in] rrs The rr list to find the key in
- * \return The DNSKEY that corresponds to the given RRSIG, or NULL if it was
- *         not found.
- */
-ldns_rr *ldns_dnssec_get_dnskey_for_rrsig(const ldns_rr *rrsig, const ldns_rr_list *rrs);
-
-/**
- * Returns the rdata field that contains the bitmap of the covered types of
- * the given NSEC record
- *
- * \param[in] nsec The nsec to get the covered type bitmap of
- * \return An ldns_rdf containing the bitmap, or NULL on error
- */
-ldns_rdf *ldns_nsec_get_bitmap(ldns_rr *nsec);
-
-
-#define LDNS_NSEC3_MAX_ITERATIONS 65535
-
-/**
- * Returns the dname of the closest (provable) encloser
- */
-ldns_rdf *
-ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
-							ldns_rr_type qtype,
-							ldns_rr_list *nsec3s);
-
-/**
- * Checks whether the packet contains rrsigs
- */
-bool
-ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt);
-
-/**
- * Returns a ldns_rr_list containing the signatures covering the given name
- * and type
- */
-ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type);
-
-/**
- * Returns a ldns_rr_list containing the signatures covering the given type
- */
-ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type);
-
-/** 
- * calculates a keytag of a key for use in DNSSEC.
- *
- * \param[in] key the key as an RR to use for the calc.
- * \return the keytag
- */
-uint16_t ldns_calc_keytag(const ldns_rr *key);
-
-/**
- * Calculates keytag of DNSSEC key, operates on wireformat rdata.
- * \param[in] key the key as uncompressed wireformat rdata.
- * \param[in] keysize length of key data.
- * \return the keytag
- */
-uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize);
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * converts a buffer holding key material to a DSA key in openssl.
- *
- * \param[in] key the key to convert
- * \return a DSA * structure with the key material
- */
-DSA *ldns_key_buf2dsa(ldns_buffer *key);
-/**
- * Like ldns_key_buf2dsa, but uses raw buffer.
- * \param[in] key the uncompressed wireformat of the key.
- * \param[in] len length of key data
- * \return a DSA * structure with the key material
- */
-DSA *ldns_key_buf2dsa_raw(unsigned char* key, size_t len);
-
-/**
- * Utility function to calculate hash using generic EVP_MD pointer.
- * \param[in] data the data to hash.
- * \param[in] len  length of data.
- * \param[out] dest the destination of the hash, must be large enough.
- * \param[in] md the message digest to use.
- * \return true if worked, false on failure.
- */
-int ldns_digest_evp(unsigned char* data, unsigned int len, 
-	unsigned char* dest, const EVP_MD* md);
-
-/**
- * Converts a holding buffer with key material to EVP PKEY in openssl.
- * Only available if ldns was compiled with GOST.
- * \param[in] key data to convert
- * \param[in] keylen length of the key data
- * \return the key or NULL on error.
- */
-EVP_PKEY* ldns_gost2pkey_raw(unsigned char* key, size_t keylen);
-
-/**
- * Converts a holding buffer with key material to EVP PKEY in openssl.
- * Only available if ldns was compiled with ECDSA.
- * \param[in] key data to convert
- * \param[in] keylen length of the key data
- * \param[in] algo precise algorithm to initialize ECC group values.
- * \return the key or NULL on error.
- */
-EVP_PKEY* ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
-
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * converts a buffer holding key material to a RSA key in openssl.
- *
- * \param[in] key the key to convert
- * \return a RSA * structure with the key material
- */
-RSA *ldns_key_buf2rsa(ldns_buffer *key);
-
-/**
- * Like ldns_key_buf2rsa, but uses raw buffer.
- * \param[in] key the uncompressed wireformat of the key.
- * \param[in] len length of key data
- * \return a RSA * structure with the key material
- */
-RSA *ldns_key_buf2rsa_raw(unsigned char* key, size_t len);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-/** 
- * returns a new DS rr that represents the given key rr.
- *
- * \param[in] *key the key to convert
- * \param[in] h the hash to use LDNS_SHA1/LDNS_SHA256
- *
- * \return ldns_rr* a new rr pointer to a DS
- */
-ldns_rr *ldns_key_rr2ds(const ldns_rr *key, ldns_hash h);
-
-/**
- * Create the type bitmap for an NSEC(3) record
- */
-ldns_rdf *
-ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
-						 size_t size,
-						 ldns_rr_type nsec_type);
-
-/**
- * returns whether a rrset of the given type is found in the rrsets.
- *
- * \param[in] rrsets the rrsets to be tested
- * \param[in] type the type to test for
- * \return int 1 if the type was found, 0 otherwise.
- */
-int
-ldns_dnssec_rrsets_contains_type (ldns_dnssec_rrsets *rrsets, ldns_rr_type type);
-
-/**
- * Creates NSEC
- */
-ldns_rr *
-ldns_dnssec_create_nsec(ldns_dnssec_name *from,
-				    ldns_dnssec_name *to,
-				    ldns_rr_type nsec_type);
-
-
-/**
- * Creates NSEC3
- */
-ldns_rr *
-ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
-					ldns_dnssec_name *to,
-					ldns_rdf *zone_name,
-					uint8_t algorithm,
-					uint8_t flags,
-					uint16_t iterations,
-					uint8_t salt_length,
-					uint8_t *salt);
-
-/**
- * Create a NSEC record
- * \param[in] cur_owner the current owner which should be taken as the starting point
- * \param[in] next_owner the rrlist which the nsec rr should point to 
- * \param[in] rrs all rrs from the zone, to find all RR types of cur_owner in
- * \return a ldns_rr with the nsec record in it
- */
-ldns_rr * ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs);
-
-/**
- * Calculates the hashed name using the given parameters
- * \param[in] *name The owner name to calculate the hash for 
- * \param[in] algorithm The hash algorithm to use
- * \param[in] iterations The number of hash iterations to use
- * \param[in] salt_length The length of the salt in bytes
- * \param[in] salt The salt to use
- * \return The hashed owner name rdf, without the domain name
- */
-ldns_rdf *ldns_nsec3_hash_name(ldns_rdf *name, uint8_t algorithm, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
-
-/**
- * Sets all the NSEC3 options. The rr to set them in must be initialized with _new() and
- * type LDNS_RR_TYPE_NSEC3
- * \param[in] *rr The RR to set the values in
- * \param[in] algorithm The NSEC3 hash algorithm 
- * \param[in] flags The flags field 
- * \param[in] iterations The number of hash iterations
- * \param[in] salt_length The length of the salt in bytes 
- * \param[in] salt The salt bytes
- */
-void ldns_nsec3_add_param_rdfs(ldns_rr *rr,
-						 uint8_t algorithm,
-						 uint8_t flags,
-						 uint16_t iterations,
-						 uint8_t salt_length,
-						 uint8_t *salt);
-
-/* this will NOT return the NSEC3  completed, you will have to run the
-   finalize function on the rrlist later! */
-ldns_rr *
-ldns_create_nsec3(ldns_rdf *cur_owner,
-                  ldns_rdf *cur_zone,
-                  ldns_rr_list *rrs,
-                  uint8_t algorithm,
-                  uint8_t flags,
-                  uint16_t iterations,
-                  uint8_t salt_length,
-                  uint8_t *salt,
-                  bool emptynonterminal);
-
-/**
- * Returns the hash algorithm used in the given NSEC3 RR
- * \param[in] *nsec3_rr The RR to read from
- * \return The algorithm identifier, or 0 on error
- */
-uint8_t ldns_nsec3_algorithm(const ldns_rr *nsec3_rr);
-
-/**
- * Returns flags field
- */
-uint8_t
-ldns_nsec3_flags(const ldns_rr *nsec3_rr);
-
-/**
- * Returns true if the opt-out flag has been set in the given NSEC3 RR
- * \param[in] *nsec3_rr The RR to read from
- * \return true if the RR has type NSEC3 and the opt-out bit has been set, false otherwise
- */
-bool ldns_nsec3_optout(const ldns_rr *nsec3_rr);
-
-/**
- * Returns the number of hash iterations used in the given NSEC3 RR
- * \param[in] *nsec3_rr The RR to read from
- * \return The number of iterations
- */
-uint16_t ldns_nsec3_iterations(const ldns_rr *nsec3_rr);
-
-/**
- * Returns the salt used in the given NSEC3 RR
- * \param[in] *nsec3_rr The RR to read from
- * \return The salt rdf, or NULL on error
- */
-ldns_rdf *ldns_nsec3_salt(const ldns_rr *nsec3_rr);
-
-/**
- * Returns the length of the salt used in the given NSEC3 RR
- * \param[in] *nsec3_rr The RR to read from
- * \return The length of the salt in bytes
- */
-uint8_t ldns_nsec3_salt_length(const ldns_rr *nsec3_rr);
-
-/**
- * Returns the salt bytes used in the given NSEC3 RR
- * \param[in] *nsec3_rr The RR to read from
- * \return The salt in bytes, this is alloced, so you need to free it
- */
-uint8_t *ldns_nsec3_salt_data(const ldns_rr *nsec3_rr);
-
-/**
- * Returns the first label of the next ownername in the NSEC3 chain (ie. without the domain)
- * \param[in] nsec3_rr The RR to read from
- * \return The first label of the next owner name in the NSEC3 chain, or NULL on error 
- */
-ldns_rdf *ldns_nsec3_next_owner(const ldns_rr *nsec3_rr);
-
-/**
- * Returns the bitmap specifying the covered types of the given NSEC3 RR
- * \param[in] *nsec3_rr The RR to read from
- * \return The covered type bitmap rdf
- */
-ldns_rdf *ldns_nsec3_bitmap(const ldns_rr *nsec3_rr);
-
-/**
- * Calculates the hashed name using the parameters of the given NSEC3 RR
- * \param[in] *nsec The RR to use the parameters from
- * \param[in] *name The owner name to calculate the hash for 
- * \return The hashed owner name rdf, without the domain name
- */
-ldns_rdf *ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name);
-
-/**
- * Check if RR type t is enumerated and set in the RR type bitmap rdf.
- * \param[in] bitmap the RR type bitmap rdf to look in
- * \param[in] type the type to check for
- * \return true when t is found and set, otherwise return false
- */
-bool ldns_nsec_bitmap_covers_type(const ldns_rdf* bitmap, ldns_rr_type type);
-
-/**
- * Checks if RR type t is enumerated in the type bitmap rdf and sets the bit.
- * \param[in] bitmap the RR type bitmap rdf to look in
- * \param[in] type the type to for which the bit to set
- * \return LDNS_STATUS_OK on success. LDNS_STATUS_TYPE_NOT_IN_BITMAP is 
- *         returned when the bitmap does not contain the bit to set.
- */
-ldns_status ldns_nsec_bitmap_set_type(ldns_rdf* bitmap, ldns_rr_type type);
-
-/**
- * Checks if RR type t is enumerated in the type bitmap rdf and clears the bit.
- * \param[in] bitmap the RR type bitmap rdf to look in
- * \param[in] type the type to for which the bit to clear
- * \return LDNS_STATUS_OK on success. LDNS_STATUS_TYPE_NOT_IN_BITMAP is 
- *         returned when the bitmap does not contain the bit to clear.
- */
-ldns_status ldns_nsec_bitmap_clear_type(ldns_rdf* bitmap, ldns_rr_type type);
-
-/**
- * Checks coverage of NSEC(3) RR name span
- * Remember that nsec and name must both be in canonical form (ie use
- * \ref ldns_rr2canonical and \ref ldns_dname2canonical prior to calling this
- * function)
- *
- * \param[in] nsec The NSEC RR to check
- * \param[in] name The owner dname to check, if the nsec record is a NSEC3 record, this should be the hashed name
- * \return true if the NSEC RR covers the owner name
- */
-bool ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name);
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * verify a packet 
- * \param[in] p the packet
- * \param[in] t the rr set type to check
- * \param[in] o the rr set name to check
- * \param[in] k list of keys
- * \param[in] s list of sigs (may be null)
- * \param[out] good_keys keys which validated the packet
- * \return status 
- * 
- */
-ldns_status ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys);
-
-/**
- * verify a packet 
- * \param[in] p the packet
- * \param[in] t the rr set type to check
- * \param[in] o the rr set name to check
- * \param[in] k list of keys
- * \param[in] s list of sigs (may be null)
- * \param[in] check_time the time for which the validation is performed
- * \param[out] good_keys keys which validated the packet
- * \return status 
- * 
- */
-ldns_status ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_list *k, ldns_rr_list *s, time_t check_time, ldns_rr_list *good_keys);
-
-#endif
-
-/**
- * chains nsec3 list
- */
-ldns_status
-ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs);
-
-/**
- * compare for nsec3 sort
- */
-int
-qsort_rr_compare_nsec3(const void *a, const void *b);
-
-/**
- * sort nsec3 list
- */
-void
-ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted);
-
-/** 
- * Default callback function to always leave present signatures, and
- * add new ones
- * \param[in] sig The signature to check for removal (unused)
- * \param[in] n Optional argument (unused)
- * \return LDNS_SIGNATURE_LEAVE_ADD_NEW
- */
-int ldns_dnssec_default_add_to_signatures(ldns_rr *sig, void *n);
-/** 
- * Default callback function to always leave present signatures, and
- * add no new ones for the keys of these signatures
- * \param[in] sig The signature to check for removal (unused)
- * \param[in] n Optional argument (unused)
- * \return LDNS_SIGNATURE_LEAVE_NO_ADD
- */
-int ldns_dnssec_default_leave_signatures(ldns_rr *sig, void *n);
-/** 
- * Default callback function to always remove present signatures, but
- * add no new ones
- * \param[in] sig The signature to check for removal (unused)
- * \param[in] n Optional argument (unused)
- * \return LDNS_SIGNATURE_REMOVE_NO_ADD
- */
-int ldns_dnssec_default_delete_signatures(ldns_rr *sig, void *n);
-/** 
- * Default callback function to always leave present signatures, and
- * add new ones
- * \param[in] sig The signature to check for removal (unused)
- * \param[in] n Optional argument (unused)
- * \return LDNS_SIGNATURE_REMOVE_ADD_NEW
- */
-int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n);
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * Converts the DSA signature from ASN1 representation (RFC2459, as 
- * used by OpenSSL) to raw signature data as used in DNS (rfc2536)
- *
- * \param[in] sig The signature in RFC2459 format
- * \param[in] sig_len The length of the signature
- * \return a new rdf with the signature
- */
-ldns_rdf *
-ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
-						  const long sig_len);
-
-/**
- * Converts the RRSIG signature RDF (in rfc2536 format) to a buffer
- * with the signature in rfc2459 format
- *
- * \param[out] target_buffer buffer to place the signature data
- * \param[in] sig_rdf The signature rdf to convert
- * \return LDNS_STATUS_OK on success, error code otherwise
- */
-ldns_status
-ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
-						  const ldns_rdf *sig_rdf);
-
-/**
- * Converts the ECDSA signature from ASN1 representation (as 
- * used by OpenSSL) to raw signature data as used in DNS
- * This routine is only present if ldns is compiled with ecdsa support.
- *
- * \param[in] sig The signature in ASN1 format
- * \param[in] sig_len The length of the signature
- * \return a new rdf with the signature
- */
-ldns_rdf *
-ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len);
-
-/**
- * Converts the RRSIG signature RDF (from DNS) to a buffer with the 
- * signature in ASN1 format as openssl uses it.
- * This routine is only present if ldns is compiled with ecdsa support.
- *
- * \param[out] target_buffer buffer to place the signature data in ASN1.
- * \param[in] sig_rdf The signature rdf to convert
- * \return LDNS_STATUS_OK on success, error code otherwise
- */
-ldns_status
-ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
-        const ldns_rdf *sig_rdf);
-
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_DNSSEC_H */
diff --git a/include/ldns/dnssec_sign.h b/include/ldns/dnssec_sign.h
deleted file mode 100644
index f51c7fb..0000000
--- a/include/ldns/dnssec_sign.h
+++ /dev/null
@@ -1,383 +0,0 @@
-/** dnssec_verify */
-
-#ifndef LDNS_DNSSEC_SIGN_H
-#define LDNS_DNSSEC_SIGN_H
-
-#include <ldns/dnssec.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* sign functions */
-
-/** Sign flag that makes DNSKEY type signed by all keys, not only by SEP keys*/
-#define LDNS_SIGN_DNSKEY_WITH_ZSK 1
-
-/**
- * Create an empty RRSIG RR (i.e. without the actual signature data)
- * \param[in] rrset The RRset to create the signature for
- * \param[in] key The key that will create the signature
- * \return signature rr
- */
-ldns_rr *
-ldns_create_empty_rrsig(ldns_rr_list *rrset,
-                        ldns_key *key);
-
-/**
- * Sign the buffer which contains the wiredata of an rrset, and the
- * corresponding empty rrsig rr with the given key
- * \param[in] sign_buf the buffer with data to sign
- * \param[in] key the key to sign with
- * \return an rdata field with the signature data
- */
-ldns_rdf *
-ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *key);
-
-/**
- * Sign an rrset
- * \param[in] rrset the rrset
- * \param[in] keys the keys to use
- * \return a rr_list with the signatures
- */
-ldns_rr_list *ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys);
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * Sign a buffer with the DSA key (hash with SHA1)
- * \param[in] to_sign buffer with the data
- * \param[in] key the key to use
- * \return a ldns_rdf with the signed data
- */
-ldns_rdf *ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key);
-
-/**
- * Sign data with EVP (general method for different algorithms)
- *
- * \param[in] to_sign The ldns_buffer containing raw data that is
- *                    to be signed
- * \param[in] key The EVP_PKEY key structure to sign with
- * \param[in] digest_type The digest algorithm to use in the creation of
- *                        the signature
- * \return ldns_rdf for the RRSIG ldns_rr
- */
-ldns_rdf *ldns_sign_public_evp(ldns_buffer *to_sign,
-						 EVP_PKEY *key,
-						 const EVP_MD *digest_type);
-
-/**
- * Sign a buffer with the RSA key (hash with SHA1)
- * \param[in] to_sign buffer with the data
- * \param[in] key the key to use
- * \return a ldns_rdf with the signed data
- */
-ldns_rdf *ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key);
-
-/**
- * Sign a buffer with the RSA key (hash with MD5)
- * \param[in] to_sign buffer with the data
- * \param[in] key the key to use
- * \return a ldns_rdf with the signed data
- */
-ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-/**
- * Marks the names in the zone that are occluded. Those names will be skipped
- * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
- * function. But watch out! Names that are partially occluded (like glue with
- * the same name as the delegation) will not be marked and should specifically 
- * be taken into account separately.
- *
- * When glue_list is given (not NULL), in the process of marking the names, all
- * glue resource records will be pushed to that list, even glue at the delegation name.
- *
- * \param[in] zone the zone in which to mark the names
- * \param[in] glue_list the list to which to push the glue rrs
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status
-ldns_dnssec_zone_mark_and_get_glue(
-		ldns_dnssec_zone *zone, ldns_rr_list *glue_list);
-
-/**
- * Marks the names in the zone that are occluded. Those names will be skipped
- * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
- * function. But watch out! Names that are partially occluded (like glue with
- * the same name as the delegation) will not be marked and should specifically 
- * be taken into account separately.
- *
- * \param[in] zone the zone in which to mark the names
- * \return LDNS_STATUS_OK on succesful completion
- */
-ldns_status
-ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone);
-
-/**
- * Finds the first dnssec_name node in the rbtree that is not occluded.
- * It *does* return names that are partially occluded.
- *
- * \param[in] node the first node to check
- * \return the first node that has not been marked as glue, or NULL
- * if not found (TODO: make that LDNS_RBTREE_NULL?)
- */
-ldns_rbnode_t *ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node);
-
-/**
- * Adds NSEC records to the given dnssec_zone
- *
- * \param[in] zone the zone to add the records to
- * \param[in] new_rrs ldns_rr's created by this function are
- *            added to this rr list, so the caller can free them later
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
-								  ldns_rr_list *new_rrs);
-
-/**
- * Adds NSEC3 records to the zone
- */
-ldns_status
-ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
-						 ldns_rr_list *new_rrs,
-						 uint8_t algorithm,
-						 uint8_t flags,
-						 uint16_t iterations,
-						 uint8_t salt_length,
-						 uint8_t *salt);
-
-/**
- * remove signatures if callback function tells to
- * 
- * \param[in] signatures list of signatures to check, and
- *            possibly remove, depending on the value of the
- *            callback
- * \param[in] key_list these are marked to be used or not,
- *            on the return value of the callback
- * \param[in] func this function is called to specify what to
- *            do with each signature (and corresponding key)
- * \param[in] arg Optional argument for the callback function
- * \returns pointer to the new signatures rrs (the original
- *          passed to this function may have been removed)
- */
-ldns_dnssec_rrs *ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
-									  ldns_key_list *key_list,
-									  int (*func)(ldns_rr *, void *),
-									  void *arg);
-
-/**
- * Adds signatures to the zone
- *
- * \param[in] zone the zone to add RRSIG Resource Records to
- * \param[in] new_rrs the RRSIG RRs that are created are also
- *            added to this list, so the caller can free them
- *            later
- * \param[in] key_list list of keys to sign with.
- * \param[in] func Callback function to decide what keys to
- *            use and what to do with old signatures
- * \param[in] arg Optional argument for the callback function
- * \param[in] flags option flags for signing process. 0 makes DNSKEY
- * RRset signed with the minimal key set, that is only SEP keys are used
- * for signing. If there are no SEP keys available, non-SEP keys will
- * be used. LDNS_SIGN_DNSKEY_WITH_ZSK makes DNSKEY type signed with all
- * keys. 0 is the default.
- * \return LDNS_STATUS_OK on success, error otherwise
- */
-ldns_status ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
-					ldns_rr_list *new_rrs,
-					ldns_key_list *key_list,
-					int (*func)(ldns_rr *, void*),
-					void *arg,
-					int flags);
-
-/**
- * Adds signatures to the zone
- *
- * \param[in] zone the zone to add RRSIG Resource Records to
- * \param[in] new_rrs the RRSIG RRs that are created are also
- *            added to this list, so the caller can free them
- *            later
- * \param[in] key_list list of keys to sign with.
- * \param[in] func Callback function to decide what keys to
- *            use and what to do with old signatures
- * \param[in] arg Optional argument for the callback function
- * \return LDNS_STATUS_OK on success, error otherwise
- */
-ldns_status ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
-								   ldns_rr_list *new_rrs,
-								   ldns_key_list *key_list,
-								   int (*func)(ldns_rr *, void*),
-								   void *arg);
-
-/**
- * signs the given zone with the given keys
- * 
- * \param[in] zone the zone to sign
- * \param[in] key_list the list of keys to sign the zone with
- * \param[in] new_rrs newly created resource records are added to this list, to free them later
- * \param[in] func callback function that decides what to do with old signatures
- *            This function takes an ldns_rr* and an optional void *arg argument, and returns one of four values:
- * LDNS_SIGNATURE_LEAVE_ADD_NEW:
- * leave the signature and add a new one for the corresponding key
- * LDNS_SIGNATURE_REMOVE_ADD_NEW:
- * remove the signature and replace is with a new one from the same key
- * LDNS_SIGNATURE_LEAVE_NO_ADD:
- * leave the signature and do not add a new one with the corresponding key
- * LDNS_SIGNATURE_REMOVE_NO_ADD:
- * remove the signature and do not replace 
- *
- * \param[in] arg optional argument for the callback function
- * \param[in] flags option flags for signing process. 0 makes DNSKEY
- * RRset signed with the minimal key set, that is only SEP keys are used
- * for signing. If there are no SEP keys available, non-SEP keys will
- * be used. LDNS_SIGN_DNSKEY_WITH_ZSK makes DNSKEY type signed with all
- * keys. 0 is the default.
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
-					ldns_rr_list *new_rrs,
-					ldns_key_list *key_list,
-					int (*func)(ldns_rr *, void *),
-					void *arg, 
-					int flags);
-
-/**
- * signs the given zone with the given new zone, with NSEC3
- *
- * \param[in] zone the zone to sign
- * \param[in] key_list the list of keys to sign the zone with
- * \param[in] new_rrs newly created resource records are added to this list, to free them later
- * \param[in] func callback function that decides what to do with old signatures
- * \param[in] arg optional argument for the callback function
- * \param[in] algorithm the NSEC3 hashing algorithm to use
- * \param[in] flags NSEC3 flags
- * \param[in] iterations the number of NSEC3 hash iterations to use
- * \param[in] salt_length the length (in octets) of the NSEC3 salt
- * \param[in] salt the NSEC3 salt data
- * \param[in] signflags option flags for signing process. 0 is the default.
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
-				ldns_rr_list *new_rrs,
-				ldns_key_list *key_list,
-				int (*func)(ldns_rr *, void *),
-				void *arg,
-				uint8_t algorithm,
-				uint8_t flags,
-				uint16_t iterations,
-				uint8_t salt_length,
-				uint8_t *salt,
-				int signflags);
-
-/**
- * signs the given zone with the given new zone, with NSEC3
- *
- * \param[in] zone the zone to sign
- * \param[in] key_list the list of keys to sign the zone with
- * \param[in] new_rrs newly created resource records are added to this list, to free them later
- * \param[in] func callback function that decides what to do with old signatures
- * \param[in] arg optional argument for the callback function
- * \param[in] algorithm the NSEC3 hashing algorithm to use
- * \param[in] flags NSEC3 flags
- * \param[in] iterations the number of NSEC3 hash iterations to use
- * \param[in] salt_length the length (in octets) of the NSEC3 salt
- * \param[in] salt the NSEC3 salt data
- * \param[in] signflags option flags for signing process. 0 is the default.
- * \param[out] map a referenced rbtree pointer variable. The newly created 
- *                 rbtree will contain mappings from hashed owner names to the 
- *                 unhashed name.
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
-				ldns_rr_list *new_rrs,
-				ldns_key_list *key_list,
-				int (*func)(ldns_rr *, void *),
-				void *arg,
-				uint8_t algorithm,
-				uint8_t flags,
-				uint16_t iterations,
-				uint8_t salt_length,
-				uint8_t *salt,
-				int signflags,
-				ldns_rbtree_t **map
-				);
-
-
-/**
- * signs the given zone with the given keys
- * 
- * \param[in] zone the zone to sign
- * \param[in] key_list the list of keys to sign the zone with
- * \param[in] new_rrs newly created resource records are added to this list, to free them later
- * \param[in] func callback function that decides what to do with old signatures
- *            This function takes an ldns_rr* and an optional void *arg argument, and returns one of four values:
- * LDNS_SIGNATURE_LEAVE_ADD_NEW:
- * leave the signature and add a new one for the corresponding key
- * LDNS_SIGNATURE_REMOVE_ADD_NEW:
- * remove the signature and replace is with a new one from the same key
- * LDNS_SIGNATURE_LEAVE_NO_ADD:
- * leave the signature and do not add a new one with the corresponding key
- * LDNS_SIGNATURE_REMOVE_NO_ADD:
- * remove the signature and do not replace 
- *
- * \param[in] arg optional argument for the callback function
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
-						    ldns_rr_list *new_rrs,
-						    ldns_key_list *key_list,
-						    int (*func)(ldns_rr *, void *),
-						    void *arg);
-
-/**
- * signs the given zone with the given new zone, with NSEC3
- *
- * \param[in] zone the zone to sign
- * \param[in] key_list the list of keys to sign the zone with
- * \param[in] new_rrs newly created resource records are added to this list, to free them later
- * \param[in] func callback function that decides what to do with old signatures
- * \param[in] arg optional argument for the callback function
- * \param[in] algorithm the NSEC3 hashing algorithm to use
- * \param[in] flags NSEC3 flags
- * \param[in] iterations the number of NSEC3 hash iterations to use
- * \param[in] salt_length the length (in octets) of the NSEC3 salt
- * \param[in] salt the NSEC3 salt data
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
-								ldns_rr_list *new_rrs,
-								ldns_key_list *key_list,
-								int (*func)(ldns_rr *, void *),
-								void *arg,
-								uint8_t algorithm,
-								uint8_t flags,
-								uint16_t iterations,
-								uint8_t salt_length,
-								uint8_t *salt);
-
-/**
- * Signs the zone, and returns a newly allocated signed zone
- * \param[in] zone the zone to sign
- * \param[in] key_list list of keys to sign with
- * \return signed zone
- */
-ldns_zone *ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list);
-
-/**
- * Signs the zone with NSEC3, and returns a newly allocated signed zone
- * \param[in] zone the zone to sign
- * \param[in] key_list list of keys to sign with
- * \param[in] algorithm the NSEC3 hashing algorithm to use
- * \param[in] flags NSEC3 flags
- * \param[in] iterations the number of NSEC3 hash iterations to use
- * \param[in] salt_length the length (in octets) of the NSEC3 salt
- * \param[in] salt the NSEC3 salt data
- * \return signed zone
- */
-ldns_zone *ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
- 
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/include/ldns/dnssec_verify.h b/include/ldns/dnssec_verify.h
deleted file mode 100644
index e8b1a91..0000000
--- a/include/ldns/dnssec_verify.h
+++ /dev/null
@@ -1,857 +0,0 @@
-/** dnssec_verify */
-
-#ifndef LDNS_DNSSEC_VERIFY_H
-#define LDNS_DNSSEC_VERIFY_H
-
-#define LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS 10
-
-#include <ldns/dnssec.h>
-#include <ldns/host2str.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Chain structure that contains all DNSSEC data needed to
- * verify an rrset
- */
-typedef struct ldns_dnssec_data_chain_struct ldns_dnssec_data_chain;
-struct ldns_dnssec_data_chain_struct
-{
-	ldns_rr_list *rrset;
-	ldns_rr_list *signatures;
-	ldns_rr_type parent_type;
-	ldns_dnssec_data_chain *parent;
-	ldns_pkt_rcode packet_rcode;
-	ldns_rr_type packet_qtype;
-	bool packet_nodata;
-};
-
-/**
- * Creates a new dnssec_chain structure
- * \return ldns_dnssec_data_chain *
- */
-ldns_dnssec_data_chain *ldns_dnssec_data_chain_new(void);
-
-/**
- * Frees a dnssec_data_chain structure
- *
- * \param[in] *chain The chain to free
- */
-void ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain);
-
-/**
- * Frees a dnssec_data_chain structure, and all data
- * contained therein
- *
- * \param[in] *chain The dnssec_data_chain to free
- */
-void ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain);
-
-/**
- * Prints the dnssec_data_chain to the given file stream
- * 
- * \param[in] *out The file stream to print to
- * \param[in] *chain The dnssec_data_chain to print
- */
-void ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain);
-
-/**
- * Prints the dnssec_data_chain to the given file stream
- * 
- * \param[in] *out The file stream to print to
- * \param[in] *fmt The format of the textual representation
- * \param[in] *chain The dnssec_data_chain to print
- */
-void ldns_dnssec_data_chain_print_fmt(FILE *out, 
-		const ldns_output_format *fmt,
-		const ldns_dnssec_data_chain *chain);
-
-/**
- * Build an ldns_dnssec_data_chain, which contains all
- * DNSSEC data that is needed to derive the trust tree later
- *
- * The data_set will be cloned
- *
- * \param[in] *res resolver structure for further needed queries
- * \param[in] qflags resolution flags
- * \param[in] *data_set The original rrset where the chain ends
- * \param[in] *pkt optional, can contain the original packet
- * (and hence the sigs and maybe the key)
- * \param[in] *orig_rr The original Resource Record
- *
- * \return the DNSSEC data chain
- */
-ldns_dnssec_data_chain *ldns_dnssec_build_data_chain(ldns_resolver *res,
-										   const uint16_t qflags,
-										   const ldns_rr_list *data_set,
-										   const ldns_pkt *pkt,
-										   ldns_rr *orig_rr);
-
-/**
- * Tree structure that contains the relation of DNSSEC data,
- * and their cryptographic status.
- *
- * This tree is derived from a data_chain, and can be used
- * to look whether there is a connection between an RRSET
- * and a trusted key. The tree only contains pointers to the
- * data_chain, and therefore one should *never* free() the
- * data_chain when there is still a trust tree derived from
- * that chain.
- *
- * Example tree:
- *     key   key    key
- *       \    |    /
- *        \   |   /
- *         \  |  /
- *            ds
- *            |
- *           key
- *            |
- *           key
- *            |
- *            rr
- *
- * For each signature there is a parent; if the parent
- * pointer is null, it couldn't be found and there was no
- * denial; otherwise is a tree which contains either a
- * DNSKEY, a DS, or a NSEC rr
- */
-typedef struct ldns_dnssec_trust_tree_struct ldns_dnssec_trust_tree;
-struct ldns_dnssec_trust_tree_struct
-{
-	ldns_rr *rr;
-	/* the complete rrset this rr was in */
-	ldns_rr_list *rrset;
-	ldns_dnssec_trust_tree *parents[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
-	ldns_status parent_status[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
-	/** for debugging, add signatures too (you might want
-	    those if they contain errors) */
-	ldns_rr *parent_signature[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
-	size_t parent_count;
-};
-
-/**
- * Creates a new (empty) dnssec_trust_tree structure
- *
- * \return ldns_dnssec_trust_tree *
- */
-ldns_dnssec_trust_tree *ldns_dnssec_trust_tree_new(void);
-
-/**
- * Frees the dnssec_trust_tree recursively
- *
- * There is no deep free; all data in the trust tree
- * consists of pointers to a data_chain
- *
- * \param[in] tree The tree to free
- */
-void ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree);
-
-/**
- * returns the depth of the trust tree
- *
- * \param[in] tree tree to calculate the depth of
- * \return The depth of the tree
- */
-size_t ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree);
-
-/**
- * Prints the dnssec_trust_tree structure to the given file
- * stream.
- *
- * If a link status is not LDNS_STATUS_OK; the status and
- * relevant signatures are printed too
- *
- * \param[in] *out The file stream to print to
- * \param[in] tree The trust tree to print
- * \param[in] tabs Prepend each line with tabs*2 spaces
- * \param[in] extended If true, add little explanation lines to the output
- */
-void ldns_dnssec_trust_tree_print(FILE *out,
-	       	ldns_dnssec_trust_tree *tree,
-		size_t tabs,
-		bool extended);
-
-/**
- * Prints the dnssec_trust_tree structure to the given file
- * stream.
- *
- * If a link status is not LDNS_STATUS_OK; the status and
- * relevant signatures are printed too
- *
- * \param[in] *out The file stream to print to
- * \param[in] *fmt The format of the textual representation
- * \param[in] tree The trust tree to print
- * \param[in] tabs Prepend each line with tabs*2 spaces
- * \param[in] extended If true, add little explanation lines to the output
- */
-void ldns_dnssec_trust_tree_print_fmt(FILE *out,
-		const ldns_output_format *fmt,
-	       	ldns_dnssec_trust_tree *tree,
-		size_t tabs,
-		bool extended);
-
-/**
- * Adds a trust tree as a parent for the given trust tree
- *
- * \param[in] *tree The tree to add the parent to
- * \param[in] *parent The parent tree to add
- * \param[in] *parent_signature The RRSIG relevant to this parent/child
- *                              connection
- * \param[in] parent_status The DNSSEC status for this parent, child and RRSIG
- * \return LDNS_STATUS_OK if the addition succeeds, error otherwise
- */
-ldns_status ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
-									 const ldns_dnssec_trust_tree *parent,
-									 const ldns_rr *parent_signature,
-									 const ldns_status parent_status);
-
-/**
- * Generates a dnssec_trust_tree for the given rr from the
- * given data_chain
- *
- * This does not clone the actual data; Don't free the
- * data_chain before you are done with this tree
- *
- * \param[in] *data_chain The chain to derive the trust tree from
- * \param[in] *rr The RR this tree will be about
- * \return ldns_dnssec_trust_tree *
- */
-ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree(
-                            ldns_dnssec_data_chain *data_chain,
-					   ldns_rr *rr);
-
-/**
- * Generates a dnssec_trust_tree for the given rr from the
- * given data_chain
- *
- * This does not clone the actual data; Don't free the
- * data_chain before you are done with this tree
- *
- * \param[in] *data_chain The chain to derive the trust tree from
- * \param[in] *rr The RR this tree will be about
- * \param[in] check_time the time for which the validation is performed
- * \return ldns_dnssec_trust_tree *
- */
-ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree_time(
-		ldns_dnssec_data_chain *data_chain, 
-		ldns_rr *rr, time_t check_time);
-
-/**
- * Sub function for derive_trust_tree that is used for a 'normal' rrset
- *
- * \param[in] new_tree The trust tree that we are building
- * \param[in] data_chain The data chain containing the data for the trust tree
- * \param[in] cur_sig_rr The currently relevant signature
- */
-void ldns_dnssec_derive_trust_tree_normal_rrset(
-         ldns_dnssec_trust_tree *new_tree,
-	    ldns_dnssec_data_chain *data_chain,
-	    ldns_rr *cur_sig_rr);
-
-/**
- * Sub function for derive_trust_tree that is used for a 'normal' rrset
- *
- * \param[in] new_tree The trust tree that we are building
- * \param[in] data_chain The data chain containing the data for the trust tree
- * \param[in] cur_sig_rr The currently relevant signature
- * \param[in] check_time the time for which the validation is performed
- */
-void ldns_dnssec_derive_trust_tree_normal_rrset_time(
-         ldns_dnssec_trust_tree *new_tree,
-	    ldns_dnssec_data_chain *data_chain,
-	    ldns_rr *cur_sig_rr, time_t check_time);
-
-
-/**
- * Sub function for derive_trust_tree that is used for DNSKEY rrsets
- *
- * \param[in] new_tree The trust tree that we are building
- * \param[in] data_chain The data chain containing the data for the trust tree
- * \param[in] cur_rr The currently relevant DNSKEY RR
- * \param[in] cur_sig_rr The currently relevant signature
- */
-void ldns_dnssec_derive_trust_tree_dnskey_rrset(
-         ldns_dnssec_trust_tree *new_tree,
-	    ldns_dnssec_data_chain *data_chain,
-	    ldns_rr *cur_rr,
-	    ldns_rr *cur_sig_rr);
-
-/**
- * Sub function for derive_trust_tree that is used for DNSKEY rrsets
- *
- * \param[in] new_tree The trust tree that we are building
- * \param[in] data_chain The data chain containing the data for the trust tree
- * \param[in] cur_rr The currently relevant DNSKEY RR
- * \param[in] cur_sig_rr The currently relevant signature
- * \param[in] check_time the time for which the validation is performed
- */
-void ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
-         ldns_dnssec_trust_tree *new_tree,
-	    ldns_dnssec_data_chain *data_chain,
-	    ldns_rr *cur_rr, ldns_rr *cur_sig_rr,
-	    time_t check_time);
-
-/**
- * Sub function for derive_trust_tree that is used for DS rrsets
- *
- * \param[in] new_tree The trust tree that we are building
- * \param[in] data_chain The data chain containing the data for the trust tree
- * \param[in] cur_rr The currently relevant DS RR
- */
-void ldns_dnssec_derive_trust_tree_ds_rrset(
-         ldns_dnssec_trust_tree *new_tree,
-	    ldns_dnssec_data_chain *data_chain,
-	    ldns_rr *cur_rr);
-
-/**
- * Sub function for derive_trust_tree that is used for DS rrsets
- *
- * \param[in] new_tree The trust tree that we are building
- * \param[in] data_chain The data chain containing the data for the trust tree
- * \param[in] cur_rr The currently relevant DS RR
- * \param[in] check_time the time for which the validation is performed
- */
-void ldns_dnssec_derive_trust_tree_ds_rrset_time(
-         ldns_dnssec_trust_tree *new_tree,
-	    ldns_dnssec_data_chain *data_chain,
-	    ldns_rr *cur_rr, time_t check_time);
-
-/**
- * Sub function for derive_trust_tree that is used when there are no
- * signatures
- *
- * \param[in] new_tree The trust tree that we are building
- * \param[in] data_chain The data chain containing the data for the trust tree
- */
-void ldns_dnssec_derive_trust_tree_no_sig(
-         ldns_dnssec_trust_tree *new_tree,
-	    ldns_dnssec_data_chain *data_chain);
-
-/**
- * Sub function for derive_trust_tree that is used when there are no
- * signatures
- *
- * \param[in] new_tree The trust tree that we are building
- * \param[in] data_chain The data chain containing the data for the trust tree
- * \param[in] check_time the time for which the validation is performed
- */
-void ldns_dnssec_derive_trust_tree_no_sig_time(
-         ldns_dnssec_trust_tree *new_tree,
-	    ldns_dnssec_data_chain *data_chain,
-	    time_t check_time);
-
-
-/**
- * Returns OK if there is a trusted path in the tree to one of 
- * the DNSKEY or DS RRs in the given list
- *
- * \param *tree The trust tree so search
- * \param *keys A ldns_rr_list of DNSKEY and DS rrs to look for
- *
- * \return LDNS_STATUS_OK if there is a trusted path to one of
- *                        the keys, or the *first* error encountered
- *                        if there were no paths
- */
-ldns_status ldns_dnssec_trust_tree_contains_keys(
-			 ldns_dnssec_trust_tree *tree,
-			 ldns_rr_list *keys);
-
-/**
- * Verifies a list of signatures for one rrset.
- *
- * \param[in] rrset the rrset to verify
- * \param[in] rrsig a list of signatures to check
- * \param[in] keys a list of keys to check with
- * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
- *                        from keys that validate one of the signatures
- *                        are added to it
- * \return status LDNS_STATUS_OK if there is at least one correct key
- */
-ldns_status ldns_verify(ldns_rr_list *rrset,
-				    ldns_rr_list *rrsig,
-				    const ldns_rr_list *keys,
-				    ldns_rr_list *good_keys);	
-
-/**
- * Verifies a list of signatures for one rrset.
- *
- * \param[in] rrset the rrset to verify
- * \param[in] rrsig a list of signatures to check
- * \param[in] keys a list of keys to check with
- * \param[in] check_time the time for which the validation is performed
- * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
- *                        from keys that validate one of the signatures
- *                        are added to it
- * \return status LDNS_STATUS_OK if there is at least one correct key
- */
-ldns_status ldns_verify_time(ldns_rr_list *rrset,
-				    ldns_rr_list *rrsig,
-				    const ldns_rr_list *keys,
-				    time_t check_time,
-				    ldns_rr_list *good_keys);	
-
-
-/**
- * Verifies a list of signatures for one rrset, but disregard the time.
- * Inception and Expiration are not checked.
- *
- * \param[in] rrset the rrset to verify
- * \param[in] rrsig a list of signatures to check
- * \param[in] keys a list of keys to check with
- * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
- *                        from keys that validate one of the signatures
- *                        are added to it
- * \return status LDNS_STATUS_OK if there is at least one correct key
- */
-ldns_status ldns_verify_notime(ldns_rr_list *rrset,
-				    ldns_rr_list *rrsig,
-				    const ldns_rr_list *keys,
-				    ldns_rr_list *good_keys);	
-
-/**
- * Tries to build an authentication chain from the given 
- * keys down to the queried domain.
- *
- * If we find a valid trust path, return the valid keys for the domain.
- * 
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \param[out] status pointer to the status variable where the result
- *                    code will be stored
- * \return the set of trusted keys for the domain, or NULL if no 
- *         trust path could be built.
- */
-ldns_rr_list *ldns_fetch_valid_domain_keys(const ldns_resolver * res,
-								   const ldns_rdf * domain,
-								   const ldns_rr_list * keys,
-								   ldns_status *status);
-
-/**
- * Tries to build an authentication chain from the given 
- * keys down to the queried domain.
- *
- * If we find a valid trust path, return the valid keys for the domain.
- * 
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \param[in] check_time the time for which the validation is performed
- * \param[out] status pointer to the status variable where the result
- *                    code will be stored
- * \return the set of trusted keys for the domain, or NULL if no 
- *         trust path could be built.
- */
-ldns_rr_list *ldns_fetch_valid_domain_keys_time(const ldns_resolver * res,
-		const ldns_rdf * domain, const ldns_rr_list * keys,
-		time_t check_time, ldns_status *status);
-
-
-/**
- * Validates the DNSKEY RRset for the given domain using the provided 
- * trusted keys.
- *
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \return the set of trusted keys for the domain, or NULL if the RRSET
- *         could not be validated
- */
-ldns_rr_list *ldns_validate_domain_dnskey (const ldns_resolver *res,
-								   const ldns_rdf *domain,
-								   const ldns_rr_list *keys);
-
-/**
- * Validates the DNSKEY RRset for the given domain using the provided 
- * trusted keys.
- *
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \param[in] check_time the time for which the validation is performed
- * \return the set of trusted keys for the domain, or NULL if the RRSET
- *         could not be validated
- */
-ldns_rr_list *ldns_validate_domain_dnskey_time(
-		const ldns_resolver *res, const ldns_rdf *domain, 
-		const ldns_rr_list *keys, time_t check_time);
-
-
-/**
- * Validates the DS RRset for the given domain using the provided trusted keys.
- *
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
- */
-ldns_rr_list *ldns_validate_domain_ds(const ldns_resolver *res,
-							   const ldns_rdf *
-							   domain,
-							   const ldns_rr_list * keys);
-
-/**
- * Validates the DS RRset for the given domain using the provided trusted keys.
- *
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \param[in] check_time the time for which the validation is performed
- * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
- */
-ldns_rr_list *ldns_validate_domain_ds_time(
-		const ldns_resolver *res, const ldns_rdf *domain, 
-		const ldns_rr_list * keys, time_t check_time);
-
-
-/**
- * Verifies a list of signatures for one RRset using a valid trust path.
- *
- * \param[in] res the current resolver
- * \param[in] rrset the rrset to verify
- * \param[in] rrsigs a list of signatures to check
- * \param[out] validating_keys  if this is a (initialized) list, the
- *                              keys from keys that validate one of
- *                              the signatures are added to it
- * \return status LDNS_STATUS_OK if there is at least one correct key
- */
-ldns_status ldns_verify_trusted(ldns_resolver *res,
-						  ldns_rr_list *rrset,
-						  ldns_rr_list *rrsigs,
-						  ldns_rr_list *validating_keys);
-
-/**
- * Verifies a list of signatures for one RRset using a valid trust path.
- *
- * \param[in] res the current resolver
- * \param[in] rrset the rrset to verify
- * \param[in] rrsigs a list of signatures to check
- * \param[in] check_time the time for which the validation is performed
- * \param[out] validating_keys  if this is a (initialized) list, the
- *                              keys from keys that validate one of
- *                              the signatures are added to it
- * \return status LDNS_STATUS_OK if there is at least one correct key
- */
-ldns_status ldns_verify_trusted_time(
-		ldns_resolver *res, ldns_rr_list *rrset, 
-		ldns_rr_list *rrsigs, time_t check_time,
-		ldns_rr_list *validating_keys);
-
-
-/**
- * denial is not just a river in egypt
- *
- * \param[in] rr The (query) RR to check the denial of existence for
- * \param[in] nsecs The list of NSEC RRs that are supposed to deny the
- *                  existence of the RR
- * \param[in] rrsigs The RRSIG RR covering the NSEC RRs
- * \return LDNS_STATUS_OK if the NSEC RRs deny the existence, error code
- *                        containing the reason they do not otherwise
- */
-ldns_status ldns_dnssec_verify_denial(ldns_rr *rr,
-							   ldns_rr_list *nsecs,
-							   ldns_rr_list *rrsigs);
-
-/**
- * Denial of existence using NSEC3 records
- * Since NSEC3 is a bit more complicated than normal denial, some
- * context arguments are needed
- *
- * \param[in] rr The (query) RR to check the denial of existence for
- * \param[in] nsecs The list of NSEC3 RRs that are supposed to deny the
- *                  existence of the RR
- * \param[in] rrsigs The RRSIG rr covering the NSEC RRs
- * \param[in] packet_rcode The RCODE value of the packet that provided the
- *                         NSEC3 RRs
- * \param[in] packet_qtype The original query RR type
- * \param[in] packet_nodata True if the providing packet had an empty ANSWER
- *                          section
- * \return LDNS_STATUS_OK if the NSEC3 RRs deny the existence, error code
- *                        containing the reason they do not otherwise
- */
-ldns_status ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
-								    ldns_rr_list *nsecs,
-								    ldns_rr_list *rrsigs,
-								    ldns_pkt_rcode packet_rcode,
-								    ldns_rr_type packet_qtype,
-								    bool packet_nodata);
-
-/**
- * Same as ldns_status ldns_dnssec_verify_denial_nsec3 but also returns
- * the nsec rr that matched.
- *
- * \param[in] rr The (query) RR to check the denial of existence for
- * \param[in] nsecs The list of NSEC3 RRs that are supposed to deny the
- *                  existence of the RR
- * \param[in] rrsigs The RRSIG rr covering the NSEC RRs
- * \param[in] packet_rcode The RCODE value of the packet that provided the
- *                         NSEC3 RRs
- * \param[in] packet_qtype The original query RR type
- * \param[in] packet_nodata True if the providing packet had an empty ANSWER
- *                          section
- * \param[in] match On match, the given (reference to a) pointer will be set 
- *                  to point to the matching nsec resource record.
- * \return LDNS_STATUS_OK if the NSEC3 RRs deny the existence, error code
- *                        containing the reason they do not otherwise
- */
-ldns_status ldns_dnssec_verify_denial_nsec3_match(ldns_rr *rr,
-						  ldns_rr_list *nsecs,
-						  ldns_rr_list *rrsigs,
-						  ldns_pkt_rcode packet_rcode,
-						  ldns_rr_type packet_qtype,
-						  bool packet_nodata,
-						  ldns_rr **match);
-/**
- * Verifies the already processed data in the buffers
- * This function should probably not be used directly.
- *
- * \param[in] rawsig_buf Buffer containing signature data to use
- * \param[in] verify_buf Buffer containing data to verify
- * \param[in] key_buf Buffer containing key data to use
- * \param[in] algo Signing algorithm
- * \return status LDNS_STATUS_OK if the data verifies. Error if not.
- */
-ldns_status ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf,
-							   ldns_buffer *verify_buf,
-							   ldns_buffer *key_buf,
-							   uint8_t algo);
-
-/**
- * Like ldns_verify_rrsig_buffers, but uses raw data.
- *
- * \param[in] sig signature data to use
- * \param[in] siglen length of signature data to use
- * \param[in] verify_buf Buffer containing data to verify
- * \param[in] key key data to use
- * \param[in] keylen length of key data to use
- * \param[in] algo Signing algorithm
- * \return status LDNS_STATUS_OK if the data verifies. Error if not.
- */
-ldns_status ldns_verify_rrsig_buffers_raw(unsigned char* sig,
-								  size_t siglen, 
-								  ldns_buffer *verify_buf,
-								  unsigned char* key,
-								  size_t keylen, 
-								  uint8_t algo);
-
-/**
- * Verifies an rrsig. All keys in the keyset are tried.
- * \param[in] rrset the rrset to check
- * \param[in] rrsig the signature of the rrset
- * \param[in] keys the keys to try
- * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
- *                        from keys that validate one of the signatures
- *                        are added to it
- * \return a list of keys which validate the rrsig + rrset. Returns
- * status LDNS_STATUS_OK if at least one key matched. Else an error.
- */
-ldns_status ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
-							   ldns_rr *rrsig,
-							   const ldns_rr_list *keys,
-							   ldns_rr_list *good_keys);
-
-/**
- * Verifies an rrsig. All keys in the keyset are tried.
- * \param[in] rrset the rrset to check
- * \param[in] rrsig the signature of the rrset
- * \param[in] keys the keys to try
- * \param[in] check_time the time for which the validation is performed
- * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
- *                        from keys that validate one of the signatures
- *                        are added to it
- * \return a list of keys which validate the rrsig + rrset. Returns
- * status LDNS_STATUS_OK if at least one key matched. Else an error.
- */
-ldns_status ldns_verify_rrsig_keylist_time(
-		ldns_rr_list *rrset, ldns_rr *rrsig, 
-		const ldns_rr_list *keys, time_t check_time,
-	       	ldns_rr_list *good_keys);
-
-
-/**
- * Verifies an rrsig. All keys in the keyset are tried. Time is not checked.
- * \param[in] rrset the rrset to check
- * \param[in] rrsig the signature of the rrset
- * \param[in] keys the keys to try
- * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
- *                        from keys that validate one of the signatures
- *                        are added to it
- * \return a list of keys which validate the rrsig + rrset. Returns
- * status LDNS_STATUS_OK if at least one key matched. Else an error.
- */
-ldns_status ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
-							   ldns_rr *rrsig,
-							   const ldns_rr_list *keys,
-							   ldns_rr_list *good_keys);
-
-/**
- * verify an rrsig with 1 key
- * \param[in] rrset the rrset
- * \param[in] rrsig the rrsig to verify
- * \param[in] key the key to use
- * \return status message wether verification succeeded.
- */
-ldns_status ldns_verify_rrsig(ldns_rr_list *rrset,
-						ldns_rr *rrsig,
-						ldns_rr *key);
-
-
-/**
- * verify an rrsig with 1 key
- * \param[in] rrset the rrset
- * \param[in] rrsig the rrsig to verify
- * \param[in] key the key to use
- * \param[in] check_time the time for which the validation is performed
- * \return status message wether verification succeeded.
- */
-ldns_status ldns_verify_rrsig_time(
-		ldns_rr_list *rrset, ldns_rr *rrsig, 
-		ldns_rr *key, time_t check_time);
-
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * verifies a buffer with signature data for a buffer with rrset data 
- * with an EVP_PKEY
- *
- * \param[in] sig the signature data
- * \param[in] rrset the rrset data, sorted and processed for verification
- * \param[in] key the EVP key structure
- * \param[in] digest_type The digest type of the signature
- */
-ldns_status ldns_verify_rrsig_evp(ldns_buffer *sig,
-						    ldns_buffer *rrset,
-						    EVP_PKEY *key,
-						    const EVP_MD *digest_type);
-
-/**
- * Like ldns_verify_rrsig_evp, but uses raw signature data.
- * \param[in] sig the signature data, wireformat uncompressed
- * \param[in] siglen length of the signature data
- * \param[in] rrset the rrset data, sorted and processed for verification
- * \param[in] key the EVP key structure
- * \param[in] digest_type The digest type of the signature
- */
-ldns_status ldns_verify_rrsig_evp_raw(unsigned char *sig,
-							   size_t siglen,
-							   ldns_buffer *rrset,
-							   EVP_PKEY *key,
-							   const EVP_MD *digest_type);
-#endif
-
-/**
- * verifies a buffer with signature data (DSA) for a buffer with rrset data 
- * with a buffer with key data.
- *
- * \param[in] sig the signature data
- * \param[in] rrset the rrset data, sorted and processed for verification
- * \param[in] key the key data
- */
-ldns_status ldns_verify_rrsig_dsa(ldns_buffer *sig,
-						    ldns_buffer *rrset,
-						    ldns_buffer *key);
-
-/**
- * verifies a buffer with signature data (RSASHA1) for a buffer with rrset data 
- * with a buffer with key data.
- *
- * \param[in] sig the signature data
- * \param[in] rrset the rrset data, sorted and processed for verification
- * \param[in] key the key data
- */
-ldns_status ldns_verify_rrsig_rsasha1(ldns_buffer *sig,
-							   ldns_buffer *rrset,
-							   ldns_buffer *key);
-
-/**
- * verifies a buffer with signature data (RSAMD5) for a buffer with rrset data 
- * with a buffer with key data.
- *
- * \param[in] sig the signature data
- * \param[in] rrset the rrset data, sorted and processed for verification
- * \param[in] key the key data
- */
-ldns_status ldns_verify_rrsig_rsamd5(ldns_buffer *sig,
-							  ldns_buffer *rrset,
-							  ldns_buffer *key);
-
-/**
- * Like ldns_verify_rrsig_dsa, but uses raw signature and key data.
- * \param[in] sig raw uncompressed wireformat signature data
- * \param[in] siglen length of signature data
- * \param[in] rrset ldns buffer with prepared rrset data.
- * \param[in] key raw uncompressed wireformat key data
- * \param[in] keylen length of key data
- */
-ldns_status ldns_verify_rrsig_dsa_raw(unsigned char* sig,
-							   size_t siglen,
-							   ldns_buffer* rrset,
-							   unsigned char* key,
-							   size_t keylen);
-
-/**
- * Like ldns_verify_rrsig_rsasha1, but uses raw signature and key data.
- * \param[in] sig raw uncompressed wireformat signature data
- * \param[in] siglen length of signature data
- * \param[in] rrset ldns buffer with prepared rrset data.
- * \param[in] key raw uncompressed wireformat key data
- * \param[in] keylen length of key data
- */
-ldns_status ldns_verify_rrsig_rsasha1_raw(unsigned char* sig,
-								  size_t siglen,
-								  ldns_buffer* rrset,
-								  unsigned char* key,
-								  size_t keylen);
-
-/**
- * Like ldns_verify_rrsig_rsasha256, but uses raw signature and key data.
- * \param[in] sig raw uncompressed wireformat signature data
- * \param[in] siglen length of signature data
- * \param[in] rrset ldns buffer with prepared rrset data.
- * \param[in] key raw uncompressed wireformat key data
- * \param[in] keylen length of key data
- */
-
-ldns_status ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
-								    size_t siglen,
-								    ldns_buffer* rrset,
-								    unsigned char* key,
-								    size_t keylen);
-
-/**
- * Like ldns_verify_rrsig_rsasha512, but uses raw signature and key data.
- * \param[in] sig raw uncompressed wireformat signature data
- * \param[in] siglen length of signature data
- * \param[in] rrset ldns buffer with prepared rrset data.
- * \param[in] key raw uncompressed wireformat key data
- * \param[in] keylen length of key data
- */
-ldns_status ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
-								    size_t siglen,
-								    ldns_buffer* rrset,
-								    unsigned char* key,
-								    size_t keylen);
-
-/**
- * Like ldns_verify_rrsig_rsamd5, but uses raw signature and key data.
- * \param[in] sig raw uncompressed wireformat signature data
- * \param[in] siglen length of signature data
- * \param[in] rrset ldns buffer with prepared rrset data.
- * \param[in] key raw uncompressed wireformat key data
- * \param[in] keylen length of key data
- */
-ldns_status ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
-								 size_t siglen,
-								 ldns_buffer* rrset,
-								 unsigned char* key,
-								 size_t keylen);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/include/ldns/dnssec_zone.h b/include/ldns/dnssec_zone.h
deleted file mode 100644
index b794f94..0000000
--- a/include/ldns/dnssec_zone.h
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * special zone file structures and functions for better dnssec handling
- *
- * A zone contains a SOA dnssec_zone_rrset, and an AVL tree of 'normal'
- * dnssec_zone_rrsets, indexed by name and type
- */
-
-#ifndef LDNS_DNSSEC_ZONE_H
-#define LDNS_DNSSEC_ZONE_H
- 
-#include <ldns/rbtree.h>
-#include <ldns/host2str.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Singly linked list of rrs
- */
-typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
-struct ldns_struct_dnssec_rrs
-{
-	ldns_rr *rr;
-	ldns_dnssec_rrs *next;
-};
-
-/**
- * Singly linked list of RRsets
- */
-typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
-struct ldns_struct_dnssec_rrsets
-{
-	ldns_dnssec_rrs *rrs;
-	ldns_rr_type type;
-	ldns_dnssec_rrs *signatures;
-	ldns_dnssec_rrsets *next;
-};
-
-/**
- * Structure containing all resource records for a domain name
- * Including the derived NSEC3, if present
- */
-typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
-struct ldns_struct_dnssec_name
-{
-	/**
-	 * pointer to a dname containing the name.
-	 * Usually points to the owner name of the first RR of the first RRset
-	 */
-	ldns_rdf *name;
-	/** 
-	 * Usually, the name is a pointer to the owner name of the first rr for
-	 * this name, but sometimes there is no actual data to point to, 
-	 * for instance in
-	 * names representing empty nonterminals. If so, set alloced to true to
-	 * indicate that this data must also be freed when the name is freed
-	 */
-	bool name_alloced;
-	/**
-	 * The rrsets for this name
-	 */
-	ldns_dnssec_rrsets *rrsets;
-	/**
-	 * NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
-	 */
-	ldns_rr *nsec;
-	/**
-	 * signatures for the NSEC record
-	 */
-	ldns_dnssec_rrs *nsec_signatures;
-	/**
-	 * Unlike what the name is_glue suggests, this field is set to true by
-	 * ldns_dnssec_zone_mark_glue() or ldns_dnssec_zone_mark_and_get_glue()
-	 * when the name, this dnssec_name struct represents, is occluded.
-	 * Names that contain other occluded rrsets and records with glue on
-	 * the delegation point will NOT have this bool set to true.
-	 * This field should NOT be read directly, but only via the 
-	 * ldns_dnssec_name_is_glue() function!
-	 */
-	bool is_glue;
-	/**
-	 * pointer to store the hashed name (only used when in an NSEC3 zone
-	 */
-	ldns_rdf *hashed_name;
-};
-
-/**
- * Structure containing a dnssec zone
- */
-struct ldns_struct_dnssec_zone {
-	/** points to the name containing the SOA RR */
-	ldns_dnssec_name *soa;
-	/** tree of ldns_dnssec_names */
-	ldns_rbtree_t *names;
-	/** tree of ldns_dnssec_names by nsec3 hashes (when applicible) */
-	ldns_rbtree_t *hashed_names;
-	/** points to the first added NSEC3 rr whose parameters will be 
-	 *  assumed for all subsequent NSEC3 rr's and which will be used
-	 *  to calculate hashed names
-	 */
-	ldns_rr *_nsec3params;
-};
-typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
-
-/**
- * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
- * \return the allocated data
- */
-ldns_dnssec_rrs *ldns_dnssec_rrs_new(void);
-
-/**
- * Frees the list of rrs, but *not* the individual ldns_rr records
- * contained in the list
- * 
- * \param[in] rrs the data structure to free
- */
-void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
-
-/**
- * Frees the list of rrs, and the individual ldns_rr records
- * contained in the list
- * 
- * \param[in] rrs the data structure to free
- */
-void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
-
-/**
- * Adds an RR to the list of RRs. The list will remain ordered.
- * If an equal RR already exists, this RR will not be added.
- *
- * \param[in] rrs the list to add to
- * \param[in] rr the RR to add
- * \return LDNS_STATUS_OK on success
- */
-ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
-
-/**
- * Prints the given rrs to the file descriptor
- *
- * \param[in] out the file descriptor to print to
- * \param[in] rrs the list of RRs to print
- */
-void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
-
-/**
- * Prints the given rrs to the file descriptor
- *
- * \param[in] out the file descriptor to print to
- * \param[in] fmt the format of the textual representation
- * \param[in] rrs the list of RRs to print
- */
-void ldns_dnssec_rrs_print_fmt(FILE *out, 
-		const ldns_output_format *fmt, ldns_dnssec_rrs *rrs);
-
-/**
- * Creates a new list (entry) of RRsets
- * \return the newly allocated structure
- */
-ldns_dnssec_rrsets *ldns_dnssec_rrsets_new(void);
-
-/**
- * Frees the list of rrsets and their rrs, but *not* the ldns_rr
- * records in the sets
- *
- * \param[in] rrsets the data structure to free
- */
-void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
-
-/**
- * Frees the list of rrsets and their rrs, and the ldns_rr
- * records in the sets
- *
- * \param[in] rrsets the data structure to free
- */
-void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
-
-/**
- * Returns the rr type of the rrset (that is head of the given list)
- *
- * \param[in] rrsets the rrset to get the type of
- * \return the rr type
- */
-ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
-
-/**
- * Sets the RR type of the rrset (that is head of the given list)
- *
- * \param[in] rrsets the rrset to set the type of
- * \param[in] type the type to set
- * \return LDNS_STATUS_OK on success
- */
-ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
-					   ldns_rr_type type);
-
-/**
- * Add an ldns_rr to the corresponding RRset in the given list of RRsets.
- * If it is not present, add it as a new RRset with 1 record.
- *
- * \param[in] rrsets the list of rrsets to add the RR to
- * \param[in] rr the rr to add to the list of rrsets
- * \return LDNS_STATUS_OK on success
- */
-ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
-
-/**
- * Print the given list of rrsets to the fiven file descriptor
- * 
- * \param[in] out the file descriptor to print to
- * \param[in] rrsets the list of RRsets to print
- * \param[in] follow if set to false, only print the first RRset
- */ 
-void ldns_dnssec_rrsets_print(FILE *out,
-		ldns_dnssec_rrsets *rrsets,
-		bool follow);
-
-/**
- * Print the given list of rrsets to the fiven file descriptor
- * 
- * \param[in] out the file descriptor to print to
- * \param[in] fmt the format of the textual representation
- * \param[in] rrsets the list of RRsets to print
- * \param[in] follow if set to false, only print the first RRset
- */ 
-void ldns_dnssec_rrsets_print_fmt(FILE *out,
-		const ldns_output_format *fmt,
-		ldns_dnssec_rrsets *rrsets,
-		bool follow);
-
-
-/**
- * Create a new data structure for a dnssec name
- * \return the allocated structure
- */
-ldns_dnssec_name *ldns_dnssec_name_new(void);
-
-/**
- * Create a new data structure for a dnssec name for the given RR
- *
- * \param[in] rr the RR to derive properties from, and to add to the name
- */
-ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
-
-/**
- * Frees the name structure and its rrs and rrsets.
- * Individual ldns_rr records therein are not freed
- *
- * \param[in] name the structure to free
- */
-void ldns_dnssec_name_free(ldns_dnssec_name *name);
-
-/**
- * Frees the name structure and its rrs and rrsets.
- * Individual ldns_rr records contained in the name are also freed
- *
- * \param[in] name the structure to free
- */
-void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
-
-/**
- * Returns the domain name of the given dnssec_name structure
- *
- * \param[in] name the dnssec name to get the domain name from
- * \return the domain name
- */
-ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
-
-
-/**
- * Sets the domain name of the given dnssec_name structure
- *
- * \param[in] name the dnssec name to set the domain name of
- * \param[in] dname the domain name to set it to. This data is *not* copied.
- */
-void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
-						 ldns_rdf *dname);
-/**
- * Returns if dnssec_name structure is marked as glue.
- * The ldns_dnssec_zone_mark_glue() function has to be called on a zone before
- * using this function.
- * Only names that have only glue rrsets will be marked.
- * Names that have other occluded rrsets and names containing glue on the 
- * delegation point will NOT be marked!
- *
- * \param[in] name the dnssec name to get the domain name from
- * \return true if the structure is marked as glue, false otherwise.
- */
-bool ldns_dnssec_name_is_glue(ldns_dnssec_name *name);
-
-/**
- * Sets the NSEC(3) RR of the given dnssec_name structure
- *
- * \param[in] name the dnssec name to set the domain name of
- * \param[in] nsec the nsec rr to set it to. This data is *not* copied.
- */
-void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
-
-/**
- * Compares the domain names of the two arguments in their
- * canonical ordening.
- * 
- * \param[in] a The first dnssec_name to compare
- * \param[in] b The second dnssec_name to compare
- * \return -1 if the domain name of a comes before that of b in canonical
- *            ordening, 1 if it is the other way around, and 0 if they are
- *            equal
- */
-int ldns_dnssec_name_cmp(const void *a, const void *b);
-
-/**
- * Inserts the given rr at the right place in the current dnssec_name
- * No checking is done whether the name matches
- *
- * \param[in] name The ldns_dnssec_name to add the RR to
- * \param[in] rr The RR to add
- * \return LDNS_STATUS_OK on success, error code otherwise
- */
-ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
-							 ldns_rr *rr);
-
-/**
- * Find the RRset with the given type in within this name structure
- *
- * \param[in] name the name to find the RRset in
- * \param[in] type the type of the RRset to find
- * \return the RRset, or NULL if not present
- */
-ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
-									   ldns_rr_type type);
-
-/**
- * Find the RRset with the given name and type in the zone
- *
- * \param[in] zone the zone structure to find the RRset in
- * \param[in] dname the domain name of the RRset to find
- * \param[in] type the type of the RRset to find
- * \return the RRset, or NULL if not present
- */
-ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
-									   ldns_rdf *dname,
-									   ldns_rr_type type);
-
-/**
- * Prints the RRs in the  dnssec name structure to the given
- * file descriptor
- *
- * \param[in] out the file descriptor to print to
- * \param[in] name the name structure to print the contents of
- */
-void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
-
-/**
- * Prints the RRs in the  dnssec name structure to the given
- * file descriptor
- *
- * \param[in] out the file descriptor to print to
- * \param[in] fmt the format of the textual representation
- * \param[in] name the name structure to print the contents of
- */
-void ldns_dnssec_name_print_fmt(FILE *out, 
-		const ldns_output_format *fmt, ldns_dnssec_name *name);
-
-/**
- * Creates a new dnssec_zone structure
- * \return the allocated structure
- */
-ldns_dnssec_zone *ldns_dnssec_zone_new(void);
-
-/**
- * Create a new dnssec zone from a file.
- * \param[out] z the new zone
- * \param[in] *fp the filepointer to use
- * \param[in] *origin the zones' origin
- * \param[in] c default class to use (IN)
- * \param[in] ttl default ttl to use
- *
- * \return ldns_status mesg with an error or LDNS_STATUS_OK
- */
-ldns_status ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp,
-		ldns_rdf* origin, uint32_t ttl, ldns_rr_class c);
-
-/**
- * Create a new dnssec zone from a file, keep track of the line numbering
- * \param[out] z the new zone
- * \param[in] *fp the filepointer to use
- * \param[in] *origin the zones' origin
- * \param[in] ttl default ttl to use
- * \param[in] c default class to use (IN)
- * \param[out] line_nr used for error msg, to get to the line number
- *
- * \return ldns_status mesg with an error or LDNS_STATUS_OK
- */
-ldns_status ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp,
-		ldns_rdf* origin, uint32_t ttl, ldns_rr_class c, int* line_nr);
-
-/**
- * Frees the given zone structure, and its rbtree of dnssec_names
- * Individual ldns_rr RRs within those names are *not* freed
- * \param[in] *zone the zone to free
- */ 
-void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
-
-/**
- * Frees the given zone structure, and its rbtree of dnssec_names
- * Individual ldns_rr RRs within those names are also freed
- * \param[in] *zone the zone to free
- */ 
-void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
-
-/**
- * Adds the given RR to the zone.
- * It find whether there is a dnssec_name with that name present.
- * If so, add it to that, if not create a new one. 
- * Special handling of NSEC and RRSIG provided
- *
- * \param[in] zone the zone to add the RR to
- * \param[in] rr The RR to add
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
-							 ldns_rr *rr);
-
-/**
- * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
- *
- * \param[in] out the file descriptor to print the names to
- * \param[in] tree the tree of ldns_dnssec_name structures to print
- * \param[in] print_soa if true, print SOA records, if false, skip them
- */
-void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
-
-/**
- * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
- *
- * \param[in] out the file descriptor to print the names to
- * \param[in] fmt the format of the textual representation
- * \param[in] tree the tree of ldns_dnssec_name structures to print
- * \param[in] print_soa if true, print SOA records, if false, skip them
- */
-void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
-		ldns_rbtree_t *tree, bool print_soa);
-
-/**
- * Prints the complete zone to the given file descriptor
- *
- * \param[in] out the file descriptor to print to
- * \param[in] zone the dnssec_zone to print
- */
-void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
-
-/**
- * Prints the complete zone to the given file descriptor
- *
- * \param[in] out the file descriptor to print to
- * \param[in] fmt the format of the textual representation
- * \param[in] zone the dnssec_zone to print
- */
-void ldns_dnssec_zone_print_fmt(FILE *out, 
-		const ldns_output_format *fmt, ldns_dnssec_zone *zone);
-
-/**
- * Adds explicit dnssec_name structures for the empty nonterminals
- * in this zone. (this is needed for NSEC3 generation)
- *
- * \param[in] zone the zone to check for empty nonterminals
- * return LDNS_STATUS_OK on success.
- */
-ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);
-
-/**
- * If a NSEC3PARAM is available in the apex, walks the zone and returns true
- * on the first optout nsec3.
- *
- * \param[in] zone the zone to check for nsec3 optout records
- * return true when the zone has at least one nsec3 optout record.
- */
-bool ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/include/ldns/duration.h b/include/ldns/duration.h
deleted file mode 100644
index f12edc4..0000000
--- a/include/ldns/duration.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * $Id: duration.h 4341 2011-01-31 15:21:09Z matthijs $
- *
- * Copyright (c) 2009 NLNet Labs. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- *
- * This file is copied from the OpenDNSSEC source repository
- * and only slightly adapted to make it fit.
- */
-
-/**
- *
- * Durations.
- */
-
-#ifndef LDNS_DURATION_H
-#define LDNS_DURATION_H
-
-#include <stdint.h>
-#include <time.h>
-
-/**
- * Duration.
- *
- */
-typedef struct ldns_duration_struct ldns_duration_type;
-struct ldns_duration_struct
-{
-    time_t years;
-    time_t months;
-    time_t weeks;
-    time_t days;
-    time_t hours;
-    time_t minutes;
-    time_t seconds;
-};
-
-/**
- * Create a new 'instant' duration.
- * \return ldns_duration_type* created duration
- *
- */
-ldns_duration_type* ldns_duration_create(void);
-
-/**
- * Compare durations.
- * \param[in] d1 one duration
- * \param[in] d2 another duration
- * \return int 0 if equal, -1 if d1 < d2, 1 if d2 < d1
- *
- */
-int ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2);
-
-/**
- * Create a duration from string.
- * \param[in] str string-format duration
- * \return ldns_duration_type* created duration
- *
- */
-ldns_duration_type* ldns_duration_create_from_string(const char* str);
-
-/**
- * Convert a duration to a string.
- * \param[in] duration duration to be converted
- * \return char* string-format duration
- *
- */
-char* ldns_duration2string(ldns_duration_type* duration);
-
-/**
- * Convert a duration to a time.
- * \param[in] duration duration to be converted
- * \return time_t time-format duration
- *
- */
-time_t ldns_duration2time(ldns_duration_type* duration);
-
-/**
- * Clean up duration.
- * \param[in] duration duration to be cleaned up
- *
- */
-void ldns_duration_cleanup(ldns_duration_type* duration);
-
-#endif /* LDNS_DURATION_H */
diff --git a/include/ldns/error.h b/include/ldns/error.h
deleted file mode 100644
index cc11958..0000000
--- a/include/ldns/error.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * \file error.h
- *
- * Defines error numbers and functions to translate those to a readable string.
- *
- */
- 
-/**
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-#ifndef LDNS_ERROR_H
-#define LDNS_ERROR_H
-
-#include <ldns/util.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum ldns_enum_status {
-	LDNS_STATUS_OK,	
-	LDNS_STATUS_EMPTY_LABEL,
-	LDNS_STATUS_LABEL_OVERFLOW,
-	LDNS_STATUS_DOMAINNAME_OVERFLOW,
-	LDNS_STATUS_DOMAINNAME_UNDERFLOW,
-	LDNS_STATUS_DDD_OVERFLOW,
-	LDNS_STATUS_PACKET_OVERFLOW,
-	LDNS_STATUS_INVALID_POINTER,
-	LDNS_STATUS_MEM_ERR,
-	LDNS_STATUS_INTERNAL_ERR,
-	LDNS_STATUS_SSL_ERR,
-	LDNS_STATUS_ERR,
-	LDNS_STATUS_INVALID_INT,
-	LDNS_STATUS_INVALID_IP4,
-	LDNS_STATUS_INVALID_IP6,
-	LDNS_STATUS_INVALID_STR,
-	LDNS_STATUS_INVALID_B32_EXT,
-	LDNS_STATUS_INVALID_B64,
-	LDNS_STATUS_INVALID_HEX,
-	LDNS_STATUS_INVALID_TIME,
-	LDNS_STATUS_NETWORK_ERR,
-	LDNS_STATUS_ADDRESS_ERR,
-	LDNS_STATUS_FILE_ERR,
-	LDNS_STATUS_UNKNOWN_INET,
-	LDNS_STATUS_NOT_IMPL,
-	LDNS_STATUS_NULL,
-	LDNS_STATUS_CRYPTO_UNKNOWN_ALGO, 
-	LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL, 	
-	LDNS_STATUS_CRYPTO_NO_RRSIG,
-	LDNS_STATUS_CRYPTO_NO_DNSKEY,
-	LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY,
-	LDNS_STATUS_CRYPTO_NO_DS,
-	LDNS_STATUS_CRYPTO_NO_TRUSTED_DS,
-	LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY,
-	LDNS_STATUS_CRYPTO_VALIDATED,
-	LDNS_STATUS_CRYPTO_BOGUS,
-	LDNS_STATUS_CRYPTO_SIG_EXPIRED,
-	LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED,
-	LDNS_STATUS_CRYPTO_TSIG_BOGUS,
-	LDNS_STATUS_CRYPTO_TSIG_ERR,
-	LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION,
-	LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR,
-	LDNS_STATUS_ENGINE_KEY_NOT_LOADED,
-	LDNS_STATUS_NSEC3_ERR,
-	LDNS_STATUS_RES_NO_NS,
-	LDNS_STATUS_RES_QUERY,
-	LDNS_STATUS_WIRE_INCOMPLETE_HEADER,
-	LDNS_STATUS_WIRE_INCOMPLETE_QUESTION,
-	LDNS_STATUS_WIRE_INCOMPLETE_ANSWER,
-	LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY,
-	LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL,
-	LDNS_STATUS_NO_DATA,
-	LDNS_STATUS_CERT_BAD_ALGORITHM,
-	LDNS_STATUS_SYNTAX_TYPE_ERR,
-	LDNS_STATUS_SYNTAX_CLASS_ERR,
-	LDNS_STATUS_SYNTAX_TTL_ERR,
-	LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL,
-	LDNS_STATUS_SYNTAX_RDATA_ERR,
-	LDNS_STATUS_SYNTAX_DNAME_ERR,
-	LDNS_STATUS_SYNTAX_VERSION_ERR,
-	LDNS_STATUS_SYNTAX_ALG_ERR,
-	LDNS_STATUS_SYNTAX_KEYWORD_ERR,
-	LDNS_STATUS_SYNTAX_TTL,
-	LDNS_STATUS_SYNTAX_ORIGIN,
-	LDNS_STATUS_SYNTAX_INCLUDE,
-	LDNS_STATUS_SYNTAX_EMPTY,
-	LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW,
-	LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR,
-	LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW,
-	LDNS_STATUS_SYNTAX_BAD_ESCAPE,
-	LDNS_STATUS_SOCKET_ERROR,
-	LDNS_STATUS_SYNTAX_ERR,
-	LDNS_STATUS_DNSSEC_EXISTENCE_DENIED,
-	LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED,
-	LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED,
-	LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND,
-	LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG,
-	LDNS_STATUS_MISSING_RDATA_FIELDS_KEY,
-	LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN,
-	LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN,
-	LDNS_STATUS_DANE_STATUS_MESSAGES,
-	LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE,
-	LDNS_STATUS_DANE_UNKNOWN_SELECTOR,
-	LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE,
-	LDNS_STATUS_DANE_UNKNOWN_PROTOCOL,
-	LDNS_STATUS_DANE_UNKNOWN_TRANSPORT,
-	LDNS_STATUS_DANE_MISSING_EXTRA_CERTS,
-	LDNS_STATUS_DANE_EXTRA_CERTS_NOT_USED,
-	LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE,
-	LDNS_STATUS_DANE_INSECURE,
-	LDNS_STATUS_DANE_BOGUS,
-	LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
-	LDNS_STATUS_DANE_NON_CA_CERTIFICATE,
-	LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE,
-	LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR,
-	LDNS_STATUS_EXISTS_ERR,
-	LDNS_STATUS_INVALID_ILNP64,
-	LDNS_STATUS_INVALID_EUI48,
-	LDNS_STATUS_INVALID_EUI64,
-	LDNS_STATUS_WIRE_RDATA_ERR,
-	LDNS_STATUS_INVALID_TAG,
-	LDNS_STATUS_TYPE_NOT_IN_BITMAP,
-	LDNS_STATUS_INVALID_RDF_TYPE,
-	LDNS_STATUS_RDATA_OVERFLOW
-};
-typedef enum ldns_enum_status ldns_status;
-
-extern ldns_lookup_table ldns_error_str[];
-
-/**
- * look up a descriptive text by each error. This function
- * could use a better name
- * \param[in] err ldns_status number
- * \return the string for that error
- */
-const char *ldns_get_errorstr_by_id(ldns_status err);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_ERROR_H */
diff --git a/include/ldns/higher.h b/include/ldns/higher.h
deleted file mode 100644
index 597e134..0000000
--- a/include/ldns/higher.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * \file higher.h
- *
- * Specifies some higher level functions that could
- * be useful for certain applications
- */
-
-/*
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-#ifndef LDNS_HIGHER_H
-#define LDNS_HIGHER_H
-
-#include <ldns/resolver.h>
-#include <ldns/rdata.h>
-#include <ldns/rr.h>
-#include <ldns/host2str.h>
-#include <ldns/tsig.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Ask the resolver about name
- * and return all address records
- * \param[in] r the resolver to use
- * \param[in] name the name to look for
- * \param[in] c the class to use
- * \param[in] flags give some optional flags to the query
- */
-ldns_rr_list *ldns_get_rr_list_addr_by_name(ldns_resolver *r, ldns_rdf *name, ldns_rr_class c, uint16_t flags);
-
-/**
- * ask the resolver about the address
- * and return the name
- * \param[in] r the resolver to use
- * \param[in] addr the addr to look for
- * \param[in] c the class to use
- * \param[in] flags give some optional flags to the query
- */
-ldns_rr_list *ldns_get_rr_list_name_by_addr(ldns_resolver *r, ldns_rdf *addr, ldns_rr_class c, uint16_t flags);
-
-/**
- * wade through fp (a /etc/hosts like file)
- * and return a rr_list containing all the 
- * defined hosts in there
- * \param[in] fp the file pointer to use
- * \return ldns_rr_list * with the names
- */
-ldns_rr_list *ldns_get_rr_list_hosts_frm_fp(FILE *fp);
-
-/**
- * wade through fp (a /etc/hosts like file)
- * and return a rr_list containing all the 
- * defined hosts in there
- * \param[in] fp the file pointer to use
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return ldns_rr_list * with the names
- */
-ldns_rr_list *ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr);
-
-/**
- * wade through fp (a /etc/hosts like file)
- * and return a rr_list containing all the 
- * defined hosts in there
- * \param[in] filename the filename to use (NULL for /etc/hosts)
- * \return ldns_rr_list * with the names
- */
-ldns_rr_list *ldns_get_rr_list_hosts_frm_file(char *filename);
-
-/**
- * This function is a wrapper function for ldns_get_rr_list_name_by_addr
- * and ldns_get_rr_list_addr_by_name. It's name is from the getaddrinfo() 
- * library call. It tries to mimic that call, but without the lowlevel
- * stuff.
- * \param[in] res The resolver. If this value is NULL then a resolver will
- * be created by ldns_getaddrinfo.
- * \param[in] node the name or ip address to look up
- * \param[in] c the class to look in
- * \param[out] list put the found RR's in this list
- * \return the number of RR found.
- */
-uint16_t ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c, ldns_rr_list **list);
-
-/**
- * Check if t is enumerated in the nsec type rdata
- * \param[in] nsec the NSEC Record to look in
- * \param[in] t the type to check for
- * \return true when t is found, otherwise return false
- */
-bool ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t);
-
-/**
- * Print a number of rdf's of the RR. The rdfnum-list must 
- * be ended by -1, otherwise unpredictable things might happen.
- * rdfs may be printed multiple times
- * \param[in] fp FILE * to write to
- * \param[in] r RR to write
- * \param[in] rdfnum a list of rdf to print.
- */
-void ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_HIGHER_H */
diff --git a/include/ldns/host2str.h b/include/ldns/host2str.h
deleted file mode 100644
index e69389e..0000000
--- a/include/ldns/host2str.h
+++ /dev/null
@@ -1,891 +0,0 @@
-/**
- * host2str.h -  txt presentation of RRs
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file
- *
- * Contains functions to translate the main structures to their text
- * representation, as well as functions to print them.
- */
-
-#ifndef LDNS_HOST2STR_H
-#define LDNS_HOST2STR_H
-
-#include <ldns/common.h>
-#include <ldns/error.h>
-#include <ldns/rr.h>
-#include <ldns/rdata.h>
-#include <ldns/packet.h>
-#include <ldns/buffer.h>
-#include <ldns/resolver.h>
-#include <ldns/zone.h>
-#include <ctype.h>
-
-#include "ldns/util.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LDNS_APL_IP4            1
-#define LDNS_APL_IP6            2
-#define LDNS_APL_MASK           0x7f
-#define LDNS_APL_NEGATION       0x80
-
-/** 
- * Represent a NULL pointer (instead of a pointer to a ldns_rr as "; (null)" 
- * as opposed to outputting nothing at all in such a case.
- */
-/*	Flag Name			Flag Nr.	Has data associated
-	---------------------------------------------------------------------*/
-#define LDNS_COMMENT_NULLS		(1 <<  0)
-/** Show key id with DNSKEY RR's as comment */
-#define LDNS_COMMENT_KEY_ID		(1 <<  1)
-/** Show if a DNSKEY is a ZSK or KSK as comment */
-#define LDNS_COMMENT_KEY_TYPE		(1 <<  2)
-/** Show DNSKEY key size as comment */
-#define LDNS_COMMENT_KEY_SIZE		(1 <<  3)
-/** Provide bubblebabble representation for DS RR's as comment */
-#define LDNS_COMMENT_BUBBLEBABBLE	(1 <<  4)
-/** Show when a NSEC3 RR has the optout flag set as comment */
-#define LDNS_COMMENT_FLAGS		(1 <<  5)
-/** Show the unhashed owner and next owner names for NSEC3 RR's as comment */
-#define LDNS_COMMENT_NSEC3_CHAIN	(1 <<  6)	/* yes */
-/** Print mark up */
-#define LDNS_COMMENT_LAYOUT		(1 <<  7)
-/** Also comment KEY_ID with RRSIGS **/
-#define LDNS_COMMENT_RRSIGS		(1 <<  8)
-#define LDNS_FMT_ZEROIZE_RRSIGS		(1 <<  9)
-#define LDNS_FMT_PAD_SOA_SERIAL		(1 << 10)
-#define LDNS_FMT_RFC3597		(1 << 11)	/* yes */
-
-#define LDNS_FMT_FLAGS_WITH_DATA			    2
-
-/** Show key id, type and size as comment for DNSKEY RR's */
-#define LDNS_COMMENT_KEY		(LDNS_COMMENT_KEY_ID  \
-					|LDNS_COMMENT_KEY_TYPE\
-					|LDNS_COMMENT_KEY_SIZE)
-
-/**
- * Output format specifier
- *
- * Determines how Packets, Resource Records and Resource record data fiels are
- * formatted when printing or converting to string.
- * Currently it is only used to specify what aspects of a Resource Record are
- * annotated in the comment section of the textual representation the record.
- * This is speciefed with flags and potential exra data (such as for example
- * a lookup map of hashes to real names for annotation NSEC3 records).
- */
-struct ldns_struct_output_format
-{
-	/** Specification of how RR's should be formatted in text */
-	int   flags;
-	/** Potential extra data to be used with formatting RR's in text */
-	void *data;
-};
-typedef struct ldns_struct_output_format ldns_output_format;
-
-/**
- * Output format struct with additional data for flags that use them.
- * This struct may not be initialized directly. Use ldns_output_format_init
- * to initialize.
- */
-struct ldns_struct_output_format_storage
-{	int   flags;
-	ldns_rbtree_t* hashmap;    /* for LDNS_COMMENT_NSEC3_CHAIN */
-	ldns_rdf*      bitmap;     /* for LDNS_FMT_RFC3597     */
-};
-typedef struct ldns_struct_output_format_storage ldns_output_format_storage;
-
-/**
- * Standard output format record that disables commenting in the textual 
- * representation of Resource Records completely.
- */
-extern const ldns_output_format *ldns_output_format_nocomments;
-/**
- * Standard output format record that annotated only DNSKEY RR's with commenti
- * text.
- */
-extern const ldns_output_format *ldns_output_format_onlykeyids;
-/**
- * The default output format record. Same as ldns_output_format_onlykeyids.
- */
-extern const ldns_output_format *ldns_output_format_default;
-/**
- * Standard output format record that shows all DNSKEY related information in
- * the comment text, plus the optout flag when set with NSEC3's, plus the
- * bubblebabble representation of DS RR's.
- */
-extern const ldns_output_format *ldns_output_format_bubblebabble;
-
-/**
- * Initialize output format storage to the default value.
- * \param[in] fmt A reference to an output_format_ storage struct
- * \return The initialized storage struct typecasted to ldns_output_format
- */
-INLINE
-ldns_output_format* ldns_output_format_init(ldns_output_format_storage* fmt) {
-	fmt->flags   = ldns_output_format_default->flags;
-	fmt->hashmap = NULL;
-	fmt->bitmap  = NULL;
-	return (ldns_output_format*)fmt;
-}
-
-/**
- * Set an ouput format flag.
- */
-INLINE void ldns_output_format_set(ldns_output_format* fmt, int flag) {
-        fmt->flags |= flag;
-}
-
-/**
- * Clear an ouput format flag.
- */
-INLINE void ldns_output_format_clear(ldns_output_format* fmt, int flag) {
-        fmt->flags &= !flag;
-}
-
-/**
- * Makes sure the LDNS_FMT_RFC3597 is set in the output format.
- * Marks the type to be printed in RFC3597 format.
- * /param[in] fmt the output format to update
- * /param[in] the type to be printed in RFC3597 format
- * /return LDNS_STATUS_OK on success
- */
-ldns_status
-ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type type);
-
-/**
- * Makes sure the LDNS_FMT_RFC3597 is set in the output format.
- * Marks the type to not be printed in RFC3597 format. When no other types
- * have been marked before, all known types (except the given one) will be
- * marked for printing in RFC3597 format.
- * /param[in] fmt the output format to update
- * /param[in] the type not to be printed in RFC3597 format
- * /return LDNS_STATUS_OK on success
- */
-ldns_status
-ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type type);
-
-/**
- * Converts an ldns packet opcode value to its mnemonic, and adds that
- * to the output buffer
- * \param[in] *output the buffer to add the data to
- * \param[in] opcode to find the string representation of
- * \return LDNS_STATUS_OK on success, or a buffer failure mode on error
- */
-ldns_status
-ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode);
-
-/**
- * Converts an ldns packet rcode value to its mnemonic, and adds that
- * to the output buffer
- * \param[in] *output the buffer to add the data to
- * \param[in] rcode to find the string representation of
- * \return LDNS_STATUS_OK on success, or a buffer failure mode on error
- */
-ldns_status
-ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode);
-
-/**
- * Converts an ldns algorithm type to its mnemonic, and adds that
- * to the output buffer
- * \param[in] *output the buffer to add the data to
- * \param[in] algorithm to find the string representation of
- * \return LDNS_STATUS_OK on success, or a buffer failure mode on error
- */
-ldns_status
-ldns_algorithm2buffer_str(ldns_buffer *output,
-                          ldns_algorithm algorithm);
-
-/**
- * Converts an ldns certificate algorithm type to its mnemonic, 
- * and adds that to the output buffer
- * \param[in] *output the buffer to add the data to
- * \param[in] cert_algorithm to find the string representation of
- * \return LDNS_STATUS_OK on success, or a buffer failure mode on error
- */
-ldns_status
-ldns_cert_algorithm2buffer_str(ldns_buffer *output,
-                               ldns_cert_algorithm cert_algorithm);
-
-
-/**
- * Converts a packet opcode to its mnemonic and returns that as
- * an allocated null-terminated string.
- * Remember to free it.
- *
- * \param[in] opcode the opcode to convert to text
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_pkt_opcode2str(ldns_pkt_opcode opcode);
-
-/**
- * Converts a packet rcode to its mnemonic and returns that as
- * an allocated null-terminated string.
- * Remember to free it.
- *
- * \param[in] rcode the rcode to convert to text
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_pkt_rcode2str(ldns_pkt_rcode rcode);
-
-/**
- * Converts a signing algorithms to its mnemonic and returns that as
- * an allocated null-terminated string.
- * Remember to free it.
- *
- * \param[in] algorithm the algorithm to convert to text
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_pkt_algorithm2str(ldns_algorithm algorithm);
-
-/**
- * Converts a cert algorithm to its mnemonic and returns that as
- * an allocated null-terminated string.
- * Remember to free it.
- *
- * \param[in] cert_algorithm to convert to text
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm);
-
-/** 
- * Converts an LDNS_RDF_TYPE_A rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_AAAA rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_STR rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_B64 rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_B32_EXT rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_HEX rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_TYPE rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_CLASS rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_ALG rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf);
-
-/**
- * Converts an ldns_rr_type value to its string representation,
- * and places it in the given buffer
- * \param[in] *output The buffer to add the data to
- * \param[in] type the ldns_rr_type to convert
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rr_type2buffer_str(ldns_buffer *output,
-                                    const ldns_rr_type type);
-
-/**
- * Converts an ldns_rr_type value to its string representation,
- * and returns that string. For unknown types, the string
- * "TYPE<id>" is returned. This function allocates data that must be
- * freed by the caller
- * \param[in] type the ldns_rr_type to convert
- * \return a newly allocated string
- */
-char *ldns_rr_type2str(const ldns_rr_type type);
-
-/**
- * Converts an ldns_rr_class value to its string representation,
- * and places it in the given buffer
- * \param[in] *output The buffer to add the data to
- * \param[in] klass the ldns_rr_class to convert
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rr_class2buffer_str(ldns_buffer *output,
-                                     const ldns_rr_class klass);
-
-/**
- * Converts an ldns_rr_class value to its string representation,
- * and returns that string. For unknown types, the string
- * "CLASS<id>" is returned. This function allocates data that must be
- * freed by the caller
- * \param[in] klass the ldns_rr_class to convert
- * \return a newly allocated string
- */
-char *ldns_rr_class2str(const ldns_rr_class klass);
-
-
-/** 
- * Converts an LDNS_RDF_TYPE_CERT rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_LOC rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_UNKNOWN rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_NSAP rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_ATMA rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_WKS rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_NSEC rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_PERIOD rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_TSIGTIME rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_tsigtime(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_APL rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_INT16_DATA rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_IPSECKEY rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf);
-
-/**
- * Converts the data in the rdata field to presentation
- * format (as char *) and appends it to the given buffer
- *
- * \param[in] output pointer to the buffer to append the data to
- * \param[in] rdf the pointer to the rdafa field containing the data
- * \return status
- */
-ldns_status ldns_rdf2buffer_str(ldns_buffer *output, const ldns_rdf *rdf);
-
-/**
- * Converts the data in the resource record to presentation
- * format (as char *) and appends it to the given buffer.
- * The presentation format of DNSKEY record is annotated with comments giving
- * the id, type and size of the key.
- *
- * \param[in] output pointer to the buffer to append the data to
- * \param[in] rr the pointer to the rr field to convert
- * \return status
- */
-ldns_status ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr);
-
-/**
- * Converts the data in the resource record to presentation
- * format (as char *) and appends it to the given buffer.
- * The presentation format is annotated with comments giving
- * additional information on the record.
- *
- * \param[in] output pointer to the buffer to append the data to
- * \param[in] fmt how to format the textual representation of the 
- *            resource record.
- * \param[in] rr the pointer to the rr field to convert
- * \return status
- */
-ldns_status ldns_rr2buffer_str_fmt(ldns_buffer *output, 
-		const ldns_output_format *fmt, const ldns_rr *rr);
-
-/**
- * Converts the data in the DNS packet to presentation
- * format (as char *) and appends it to the given buffer
- *
- * \param[in] output pointer to the buffer to append the data to
- * \param[in] pkt the pointer to the packet to convert
- * \return status
- */
-ldns_status ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
-
-/**
- * Converts the data in the DNS packet to presentation
- * format (as char *) and appends it to the given buffer
- *
- * \param[in] output pointer to the buffer to append the data to
- * \param[in] fmt how to format the textual representation of the packet
- * \param[in] pkt the pointer to the packet to convert
- * \return status
- */
-ldns_status ldns_pkt2buffer_str_fmt(ldns_buffer *output,
-		const ldns_output_format *fmt, const ldns_pkt *pkt);
-
-/** 
- * Converts an LDNS_RDF_TYPE_NSEC3_SALT rdata element to string format and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf);
-
-
-/**
- * Converts the data in the DNS packet to presentation
- * format (as char *) and appends it to the given buffer
- *
- * \param[in] output pointer to the buffer to append the data to
- * \param[in] k the pointer to the private key to convert
- * \return status
- */
-ldns_status ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k);
-
-/**
- * Converts an LDNS_RDF_TYPE_INT8 rdata element to string format and adds it to the output buffer
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf);
-
-/**
- * Converts an LDNS_RDF_TYPE_INT16 rdata element to string format and adds it to the output buffer
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf);
-
-/**
- * Converts an LDNS_RDF_TYPE_INT32 rdata element to string format and adds it to the output buffer
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf);
-
-/**
- * Converts an LDNS_RDF_TYPE_TIME rdata element to string format and adds it to the output buffer
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_ILNP64 rdata element to 4 hexadecimal numbers
- * separated by colons and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_ilnp64(ldns_buffer *output,
-		const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_EUI48 rdata element to 6 hexadecimal numbers
- * separated by dashes and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_eui48(ldns_buffer *output,
-		const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_EUI64 rdata element to 8 hexadecimal numbers
- * separated by dashes and adds it to the output buffer 
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_eui64(ldns_buffer *output,
-		const ldns_rdf *rdf);
-
-/** 
- * Adds the LDNS_RDF_TYPE_TAG rdata to the output buffer,
- * provided it contains only alphanumeric characters.
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_tag(ldns_buffer *output,
-		const ldns_rdf *rdf);
-
-/** 
- * Adds the LDNS_RDF_TYPE_LONG_STR rdata to the output buffer, in-between 
- * double quotes and all non printable characters properly escaped.
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_long_str(ldns_buffer *output,
-	       	const ldns_rdf *rdf);
-
-/** 
- * Converts an LDNS_RDF_TYPE_HIP rdata element to presentation format for
- * the algorithm, HIT and Public Key and adds it the output buffer .
- * \param[in] *rdf The rdata to convert
- * \param[in] *output The buffer to add the data to
- * \return LDNS_STATUS_OK on success, and error status on failure
- */
-ldns_status ldns_rdf2buffer_str_hip(ldns_buffer *output,
-		const ldns_rdf *rdf);
-
-/**
- * Converts the data in the rdata field to presentation format and
- * returns that as a char *.
- * Remember to free it.
- *
- * \param[in] rdf The rdata field to convert
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_rdf2str(const ldns_rdf *rdf);
-
-/**
- * Converts the data in the resource record to presentation format and
- * returns that as a char *.
- * Remember to free it.
- *
- * \param[in] rr The rdata field to convert
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_rr2str(const ldns_rr *rr);
-
-/**
- * Converts the data in the resource record to presentation format and
- * returns that as a char *.
- * Remember to free it.
- *
- * \param[in] fmt how to format the resource record
- * \param[in] rr The rdata field to convert
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr);
-
-/**
- * Converts the data in the DNS packet to presentation format and
- * returns that as a char *.
- * Remember to free it.
- *
- * \param[in] pkt The rdata field to convert
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_pkt2str(const ldns_pkt *pkt);
-
-/**
- * Converts the data in the DNS packet to presentation format and
- * returns that as a char *.
- * Remember to free it.
- *
- * \param[in] fmt how to format the packet
- * \param[in] pkt The rdata field to convert
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt);
-
-/**
- * Converts a private key to the test presentation fmt and
- * returns that as a char *.
- * Remember to free it.
- *
- * \param[in] k the key to convert to text
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_key2str(const ldns_key *k);
-
-/**
- * Converts a list of resource records to presentation format
- * and returns that as a char *.
- * Remember to free it.
- *
- * \param[in] rr_list the rr_list to convert to text
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_rr_list2str(const ldns_rr_list *rr_list);
-
-/**
- * Converts a list of resource records to presentation format
- * and returns that as a char *.
- * Remember to free it.
- *
- * \param[in] fmt how to format the list of resource records
- * \param[in] rr_list the rr_list to convert to text
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_rr_list2str_fmt(
-		const ldns_output_format *fmt, const ldns_rr_list *rr_list);
-
-/**
- * Returns a copy of the data in the buffer as a null terminated
- * char * string. The returned string must be freed by the caller.
- * The buffer must be in write modus and may thus not have been flipped.
- *
- * \param[in] buffer buffer containing char * data
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_buffer2str(ldns_buffer *buffer);
-
-/**
- * Exports and returns the data in the buffer as a null terminated
- * char * string. The returned string must be freed by the caller.
- * The buffer must be in write modus and may thus not have been flipped.
- * The buffer is fixed after this function returns.
- *
- * \param[in] buffer buffer containing char * data
- * \return null terminated char * data, or NULL on error
- */
-char *ldns_buffer_export2str(ldns_buffer *buffer);
-
-/**
- * Prints the data in the rdata field to the given file stream
- * (in presentation format)
- *
- * \param[in] output the file stream to print to
- * \param[in] rdf the rdata field to print
- * \return void
- */
-void ldns_rdf_print(FILE *output, const ldns_rdf *rdf);
-
-/**
- * Prints the data in the resource record to the given file stream
- * (in presentation format)
- *
- * \param[in] output the file stream to print to
- * \param[in] rr the resource record to print
- * \return void
- */
-void ldns_rr_print(FILE *output, const ldns_rr *rr);
-
-/**
- * Prints the data in the resource record to the given file stream
- * (in presentation format)
- *
- * \param[in] output the file stream to print to
- * \param[in] fmt format of the textual representation
- * \param[in] rr the resource record to print
- * \return void
- */
-void ldns_rr_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_rr *rr);
-
-/**
- * Prints the data in the DNS packet to the given file stream
- * (in presentation format)
- *
- * \param[in] output the file stream to print to
- * \param[in] pkt the packet to print
- * \return void
- */
-void ldns_pkt_print(FILE *output, const ldns_pkt *pkt);
-
-/**
- * Prints the data in the DNS packet to the given file stream
- * (in presentation format)
- *
- * \param[in] output the file stream to print to
- * \param[in] fmt format of the textual representation
- * \param[in] pkt the packet to print
- * \return void
- */
-void ldns_pkt_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_pkt *pkt);
-
-/**
- * Converts a rr_list to presentation format and appends it to
- * the output buffer
- * \param[in] output the buffer to append output to
- * \param[in] list the ldns_rr_list to print
- * \return ldns_status
- */
-ldns_status ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list);
-
-/**
- * Converts a rr_list to presentation format and appends it to
- * the output buffer
- * \param[in] output the buffer to append output to
- * \param[in] fmt format of the textual representation
- * \param[in] list the ldns_rr_list to print
- * \return ldns_status
- */
-ldns_status ldns_rr_list2buffer_str_fmt(ldns_buffer *output, 
-		const ldns_output_format *fmt, const ldns_rr_list *list);
-
-/**
- * Converts the header of a packet to presentation format and appends it to
- * the output buffer
- * \param[in] output the buffer to append output to
- * \param[in] pkt the packet to convert the header of
- * \return ldns_status
- */
-ldns_status ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
-
-/**
- * print a rr_list to output
- * \param[in] output the fd to print to
- * \param[in] list the rr_list to print
- */
-void ldns_rr_list_print(FILE *output, const ldns_rr_list *list);
-
-/**
- * print a rr_list to output
- * \param[in] output the fd to print to
- * \param[in] fmt format of the textual representation
- * \param[in] list the rr_list to print
- */
-void ldns_rr_list_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_rr_list *list);
-
-/**
- * Print a resolver (in sofar that is possible) state
- * to output.
- * \param[in] output the fd to print to
- * \param[in] r the resolver to print
- */
-void ldns_resolver_print(FILE *output, const ldns_resolver *r);
-
-/**
- * Print a resolver (in sofar that is possible) state
- * to output.
- * \param[in] output the fd to print to
- * \param[in] fmt format of the textual representation
- * \param[in] r the resolver to print
- */
-void ldns_resolver_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_resolver *r);
-
-/**
- * Print a zone structure * to output. Note the SOA record
- * is included in this output
- * \param[in] output the fd to print to
- * \param[in] z the zone to print
- */
-void ldns_zone_print(FILE *output, const ldns_zone *z);
-
-/**
- * Print a zone structure * to output. Note the SOA record
- * is included in this output
- * \param[in] output the fd to print to
- * \param[in] fmt format of the textual representation
- * \param[in] z the zone to print
- */
-void ldns_zone_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_zone *z);
-
-/**
- * Print the ldns_rdf containing a dname to the buffer
- * \param[in] output the buffer to print to
- * \param[in] dname the dname to print
- * \return ldns_status message if the printing succeeded
- */
-ldns_status ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_HOST2STR_H */
diff --git a/include/ldns/host2wire.h b/include/ldns/host2wire.h
deleted file mode 100644
index 94693cd..0000000
--- a/include/ldns/host2wire.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * host2wire.h - 2wire conversion routines
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file
- *
- * Contains all functions to translate the main structures to wire format
- */
-
-#ifndef LDNS_HOST2WIRE_H
-#define LDNS_HOST2WIRE_H
-
-#include <ldns/common.h>
-#include <ldns/error.h>
-#include <ldns/rr.h>
-#include <ldns/rdata.h>
-#include <ldns/packet.h>
-#include <ldns/buffer.h>
-#include <ctype.h>
-
-#include "ldns/util.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Copies the dname data to the buffer in wire format
- * \param[out] *buffer buffer to append the result to
- * \param[in] *name rdata dname to convert
- * \return ldns_status
- */
-ldns_status ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name);
-
-/**
- * Copies the dname data to the buffer in wire format
- * \param[out] *buffer buffer to append the result to
- * \param[in] *name rdata dname to convert
- * \param[out] *compression_data data structure holding state for compression
- * \return ldns_status
- */
-ldns_status ldns_dname2buffer_wire_compress(ldns_buffer *buffer, const ldns_rdf *name, ldns_rbtree_t *compression_data);
-
-/**
- * Copies the rdata data to the buffer in wire format
- * \param[out] *output buffer to append the result to
- * \param[in] *rdf rdata to convert
- * \return ldns_status
- */
-ldns_status ldns_rdf2buffer_wire(ldns_buffer *output, const ldns_rdf *rdf);
-
-/**
- * Copies the rdata data to the buffer in wire format
- * \param[out] *output buffer to append the result to
- * \param[in] *rdf rdata to convert
- * \param[out] *compression_data data structure holding state for compression
- * \return ldns_status
- */
-ldns_status ldns_rdf2buffer_wire_compress(ldns_buffer *output, const ldns_rdf *rdf, ldns_rbtree_t *compression_data);
-
-/**
- * Copies the rdata data to the buffer in wire format
- * If the rdata is a dname, the letters will be lowercased
- * during the conversion
- * \param[out] *output buffer to append the result to
- * \param[in] *rdf rdata to convert
- * \return ldns_status
- */
-ldns_status ldns_rdf2buffer_wire_canonical(ldns_buffer *output,
-								   const ldns_rdf *rdf);
-
-/**
- * Copies the rr data to the buffer in wire format
- * \param[out] *output buffer to append the result to
- * \param[in] *rr resource record to convert
- * \param[in] section the section in the packet this rr is supposed to be in
- *            (to determine whether to add rdata or not)
- * \return ldns_status
- */
-ldns_status ldns_rr2buffer_wire(ldns_buffer *output,
-						  const ldns_rr *rr,
-						  int section);
-
-/**
- * Copies the rr data to the buffer in wire format while doing DNAME compression
- * \param[out] *output buffer to append the result to
- * \param[in] *rr resource record to convert
- * \param[in] section the section in the packet this rr is supposed to be in
- *            (to determine whether to add rdata or not)
- * \param[out] *compression_data data structure holding state information for compression
- * \return ldns_status
- */
-ldns_status ldns_rr2buffer_wire_compress(ldns_buffer *output,
-						  const ldns_rr *rr,
-						  int section,
-						  ldns_rbtree_t *compression_data);
-
-/**
- * Copies the rr data to the buffer in wire format, in canonical format
- * according to RFC3597 (every dname in rdata fields of RR's mentioned in
- * that RFC will be lowercased)
- * \param[out] *output buffer to append the result to
- * \param[in] *rr resource record to convert
- * \param[in] section the section in the packet this rr is supposed to be in
- *            (to determine whether to add rdata or not)
- * \return ldns_status
- */
-ldns_status ldns_rr2buffer_wire_canonical(ldns_buffer *output,
-								  const ldns_rr *rr,
-								  int section);
-
-
-/**
- * Converts a rrsig to wireformat BUT EXCLUDE the rrsig rdata
- * This is needed in DNSSEC verification
- * \param[out] output buffer to append the result to
- * \param[in] sigrr signature rr to operate on
- * \return ldns_status
- */
-ldns_status ldns_rrsig2buffer_wire(ldns_buffer *output, const ldns_rr *sigrr);
-
-/**
- * Converts an rr's rdata to wireformat, while excluding
- * the ownername and all the stuff before the rdata.
- * This is needed in DNSSEC keytag calculation, the ds
- * calcalution from the key and maybe elsewhere.
- *
- * \param[out] *output buffer where to put the result
- * \param[in] *rr rr to operate on
- * \return ldns_status
- */
-ldns_status ldns_rr_rdata2buffer_wire(ldns_buffer *output, const ldns_rr *rr);
-
-/**
- * Copies the packet data to the buffer in wire format
- * \param[out] *output buffer to append the result to
- * \param[in] *pkt packet to convert
- * \return ldns_status
- */
-ldns_status ldns_pkt2buffer_wire(ldns_buffer *output, const ldns_pkt *pkt);
-
-/**
- * Copies the rr_list data to the buffer in wire format
- * \param[out] *output buffer to append the result to
- * \param[in] *rrlist rr_list to to convert
- * \return ldns_status
- */
-ldns_status ldns_rr_list2buffer_wire(ldns_buffer *output, const ldns_rr_list *rrlist);
-
-/**
- * Allocates an array of uint8_t at dest, and puts the wireformat of the
- * given rdf in that array. The result_size value contains the
- * length of the array, if it succeeds, and 0 otherwise (in which case
- * the function also returns NULL)
- *
- * \param[out] dest pointer to the array of bytes to be created
- * \param[in] rdf the rdata field to convert
- * \param[out] size the size of the converted result
- */
-ldns_status ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *size);
-
-/**
- * Allocates an array of uint8_t at dest, and puts the wireformat of the
- * given rr in that array. The result_size value contains the
- * length of the array, if it succeeds, and 0 otherwise (in which case
- * the function also returns NULL)
- *
- * If the section argument is LDNS_SECTION_QUESTION, data like ttl and rdata
- * are not put into the result
- *
- * \param[out] dest pointer to the array of bytes to be created
- * \param[in] rr the rr to convert
- * \param[in] section the rr section, determines how the rr is written.
- * \param[out] size the size of the converted result
- */
-ldns_status ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *size);
-
-/**
- * Allocates an array of uint8_t at dest, and puts the wireformat of the
- * given packet in that array. The result_size value contains the
- * length of the array, if it succeeds, and 0 otherwise (in which case
- * the function also returns NULL)
- */
-ldns_status ldns_pkt2wire(uint8_t **dest, const ldns_pkt *p, size_t *size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_HOST2WIRE_H */
diff --git a/include/ldns/keys.h b/include/ldns/keys.h
deleted file mode 100644
index d3b4873..0000000
--- a/include/ldns/keys.h
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * 
- * keys.h
- *
- * priv key definitions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file
- *
- * Addendum to \ref dnssec.h, this module contains key and algorithm definitions and functions.
- */
- 
-
-#ifndef LDNS_KEYS_H
-#define LDNS_KEYS_H
-
-#include <ldns/common.h>
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-#include <openssl/ssl.h>
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-#include <ldns/util.h>
-#include <errno.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern ldns_lookup_table ldns_signing_algorithms[];
-
-#define LDNS_KEY_ZONE_KEY 0x0100   /* rfc 4034 */
-#define LDNS_KEY_SEP_KEY 0x0001    /* rfc 4034 */
-#define LDNS_KEY_REVOKE_KEY 0x0080 /* rfc 5011 */
-
-/**
- * Algorithms used in dns
- */
-enum ldns_enum_algorithm
-{
-        LDNS_RSAMD5             = 1,   /* RFC 4034,4035 */
-        LDNS_DH                 = 2,
-        LDNS_DSA                = 3,
-        LDNS_ECC                = 4,
-        LDNS_RSASHA1            = 5,
-        LDNS_DSA_NSEC3          = 6,
-        LDNS_RSASHA1_NSEC3      = 7,
-        LDNS_RSASHA256          = 8,   /* RFC 5702 */
-        LDNS_RSASHA512          = 10,  /* RFC 5702 */
-        LDNS_ECC_GOST           = 12,  /* RFC 5933 */
-        LDNS_ECDSAP256SHA256    = 13,  /* RFC 6605 */
-        LDNS_ECDSAP384SHA384    = 14,  /* RFC 6605 */
-        LDNS_INDIRECT           = 252,
-        LDNS_PRIVATEDNS         = 253,
-        LDNS_PRIVATEOID         = 254
-};
-typedef enum ldns_enum_algorithm ldns_algorithm;
-
-/**
- * Hashing algorithms used in the DS record
- */
-enum ldns_enum_hash
-{
-        LDNS_SHA1               = 1,  /* RFC 4034 */
-        LDNS_SHA256             = 2,  /* RFC 4509 */
-        LDNS_HASH_GOST          = 3,  /* RFC 5933 */
-        LDNS_SHA384             = 4   /* RFC 6605 */
-};
-typedef enum ldns_enum_hash ldns_hash;
-
-/**
- * Algorithms used in dns for signing
- */
-enum ldns_enum_signing_algorithm
-{
-	LDNS_SIGN_RSAMD5	 = LDNS_RSAMD5,
-	LDNS_SIGN_RSASHA1	 = LDNS_RSASHA1,
-	LDNS_SIGN_DSA		 = LDNS_DSA,
-	LDNS_SIGN_RSASHA1_NSEC3  = LDNS_RSASHA1_NSEC3,
-	LDNS_SIGN_RSASHA256	 = LDNS_RSASHA256,
-	LDNS_SIGN_RSASHA512	 = LDNS_RSASHA512,
-	LDNS_SIGN_DSA_NSEC3	 = LDNS_DSA_NSEC3,
-	LDNS_SIGN_ECC_GOST       = LDNS_ECC_GOST,
-        LDNS_SIGN_ECDSAP256SHA256 = LDNS_ECDSAP256SHA256,
-        LDNS_SIGN_ECDSAP384SHA384 = LDNS_ECDSAP384SHA384,
-	LDNS_SIGN_HMACMD5	 = 157,	/* not official! This type is for TSIG, not DNSSEC */
-	LDNS_SIGN_HMACSHA1	 = 158,	/* not official! This type is for TSIG, not DNSSEC */
-	LDNS_SIGN_HMACSHA256 = 159  /* ditto */
-};
-typedef enum ldns_enum_signing_algorithm ldns_signing_algorithm;
-
-/**
- * General key structure, can contain all types of keys that
- * are used in DNSSEC. Mostly used to store private keys, since
- * public keys can also be stored in a \ref ldns_rr with type
- * \ref LDNS_RR_TYPE_DNSKEY.
- *
- * This structure can also store some variables that influence the
- * signatures generated by signing with this key, for instance the
- * inception date.
- */
-struct ldns_struct_key {
-	ldns_signing_algorithm _alg;
-	/** Whether to use this key when signing */
-	bool _use;
-	/** Storage pointers for the types of keys supported */
-	/* TODO remove unions? */
-	struct {
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-#ifndef S_SPLINT_S
-		/* The key can be an OpenSSL EVP Key
-		 */
-		EVP_PKEY *key;
-#endif
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-		/**
-		 * The key can be an HMAC key
-		 */
-		struct {
-			unsigned char *key;
-			size_t size;
-		} hmac;
-		/** the key structure can also just point to some external
-		 *  key data
-		 */
-		void *external_key;
-	} _key;
-	/** Depending on the key we can have extra data */
-	union {
-                /** Some values that influence generated signatures */
-		struct {
-			/** The TTL of the rrset that is currently signed */
-			uint32_t orig_ttl;
-			/** The inception date of signatures made with this key. */
-			uint32_t inception;
-			/** The expiration date of signatures made with this key. */
-			uint32_t expiration;
-			/** The keytag of this key. */
-			uint16_t keytag;
-			/** The dnssec key flags as specified in RFC4035, like ZSK and KSK */
-			uint16_t flags;
-		}  dnssec;
-	} _extra;
-	/** Owner name of the key */
-	ldns_rdf *_pubkey_owner;
-};
-typedef struct ldns_struct_key ldns_key;
-
-/**
- * Same as rr_list, but now for keys 
- */
-struct ldns_struct_key_list
-{
-	size_t _key_count;
-	ldns_key **_keys;
-};
-typedef struct ldns_struct_key_list ldns_key_list;
-
-
-/**
- * Creates a new empty key list
- * \return a new ldns_key_list structure pointer
- */
-ldns_key_list *ldns_key_list_new(void);
-
-/** 
- * Creates a new empty key structure
- * \return a new ldns_key * structure
- */
-ldns_key *ldns_key_new(void);
-
-/**
- * Creates a new key based on the algorithm
- *
- * \param[in] a The algorithm to use
- * \param[in] size the number of bytes for the keysize
- * \return a new ldns_key structure with the key
- */
-ldns_key *ldns_key_new_frm_algorithm(ldns_signing_algorithm a, uint16_t size);
-
-/**
- * Creates a new priv key based on the 
- * contents of the file pointed by fp.
- *
- * The file should be in Private-key-format v1.x.
- *
- * \param[out] k the new ldns_key structure
- * \param[in] fp the file pointer to use
- * \return an error or LDNS_STATUS_OK
- */
-ldns_status ldns_key_new_frm_fp(ldns_key **k, FILE *fp);
-
-/**
- * Creates a new private key based on the 
- * contents of the file pointed by fp
- *
- * The file should be in Private-key-format v1.x.
- *
- * \param[out] k the new ldns_key structure
- * \param[in] fp the file pointer to use
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return an error or LDNS_STATUS_OK
- */
-ldns_status ldns_key_new_frm_fp_l(ldns_key **k, FILE *fp, int *line_nr);
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * Read the key with the given id from the given engine and store it
- * in the given ldns_key structure. The algorithm type is set
- */
-ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm);
-
-
-/**
- * frm_fp helper function. This function parses the
- * remainder of the (RSA) priv. key file generated from bind9
- * \param[in] fp the file to parse
- * \return NULL on failure otherwise a RSA structure
- */
-RSA *ldns_key_new_frm_fp_rsa(FILE *fp);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * frm_fp helper function. This function parses the
- * remainder of the (RSA) priv. key file generated from bind9
- * \param[in] fp the file to parse
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return NULL on failure otherwise a RSA structure
- */
-RSA *ldns_key_new_frm_fp_rsa_l(FILE *fp, int *line_nr);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * frm_fp helper function. This function parses the
- * remainder of the (DSA) priv. key file
- * \param[in] fp the file to parse
- * \return NULL on failure otherwise a RSA structure
- */
-DSA *ldns_key_new_frm_fp_dsa(FILE *fp);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * frm_fp helper function. This function parses the
- * remainder of the (DSA) priv. key file
- * \param[in] fp the file to parse
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return NULL on failure otherwise a RSA structure
- */
-DSA *ldns_key_new_frm_fp_dsa_l(FILE *fp, int *line_nr);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * frm_fp helper function. This function parses the
- * remainder of the (HMAC-MD5) key file
- * This function allocated a buffer that needs to be freed
- * \param[in] fp the file to parse
- * \param[out] hmac_size the number of bits in the resulting buffer
- * \return NULL on failure otherwise a newly allocated char buffer
- */
-unsigned char *ldns_key_new_frm_fp_hmac(FILE *fp, size_t *hmac_size);
-#endif
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * frm_fp helper function. This function parses the
- * remainder of the (HMAC-MD5) key file
- * This function allocated a buffer that needs to be freed
- * \param[in] fp the file to parse
- * \param[in] line_nr pointer to an integer containing the current line number (for error reporting purposes)
- * \param[out] hmac_size the number of bits in the resulting buffer
- * \return NULL on failure otherwise a newly allocated char buffer
- */
-unsigned char *ldns_key_new_frm_fp_hmac_l(FILE *fp, int *line_nr, size_t *hmac_size);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-/* acces write functions */
-/**
- * Set the key's algorithm
- * \param[in] k the key
- * \param[in] l the algorithm
- */
-void ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l);
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * Set the key's evp key
- * \param[in] k the key
- * \param[in] e the evp key
- */
-void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e);
-
-/**
- * Set the key's rsa data.
- * The rsa data should be freed by the user.
- * \param[in] k the key
- * \param[in] r the rsa data
- */
-void ldns_key_set_rsa_key(ldns_key *k, RSA *r);
-
-/**
- * Set the key's dsa data
- * The dsa data should be freed by the user.
- * \param[in] k the key
- * \param[in] d the dsa data
- */
-void ldns_key_set_dsa_key(ldns_key *k, DSA *d);
-
-/**
- * Assign the key's rsa data
- * The rsa data will be freed automatically when the key is freed.
- * \param[in] k the key
- * \param[in] r the rsa data
- */
-void ldns_key_assign_rsa_key(ldns_key *k, RSA *r);
-
-/**
- * Assign the key's dsa data
- * The dsa data will be freed automatically when the key is freed.
- * \param[in] k the key
- * \param[in] d the dsa data
- */
-void ldns_key_assign_dsa_key(ldns_key *k, DSA *d);
-
-/** 
- * Get the PKEY id for GOST, loads GOST into openssl as a side effect.
- * Only available if GOST is compiled into the library and openssl.
- * \return the gost id for EVP_CTX creation.
- */
-int ldns_key_EVP_load_gost_id(void);
-
-/** Release the engine reference held for the GOST engine. */
-void ldns_key_EVP_unload_gost(void);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-/**
- * Set the key's hmac data
- * \param[in] k the key
- * \param[in] hmac the raw key data
- */
-void ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac);
-
-/**
- * Set the key id data. This is used if the key points to
- * some externally stored key data
- * 
- * Only the pointer is set, the data there is not copied,
- * and must be freed manually; ldns_key_deep_free() does 
- * *not* free this data
- * \param[in] key the key
- * \param[in] external_key key id data
- */
-void ldns_key_set_external_key(ldns_key *key, void *external_key);
-
-/**
- * Set the key's hmac size
- * \param[in] k the key
- * \param[in] hmac_size the size of the hmac data
- */
-void ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size);
-/**
- * Set the key's original ttl
- * \param[in] k the key
- * \param[in] t the ttl
- */
-void ldns_key_set_origttl(ldns_key *k, uint32_t t);
-/**
- * Set the key's inception date (seconds after epoch)
- * \param[in] k the key
- * \param[in] i the inception
- */
-void ldns_key_set_inception(ldns_key *k, uint32_t i);
-/**
- * Set the key's expiration date (seconds after epoch)
- * \param[in] k the key
- * \param[in] e the expiration
- */
-void ldns_key_set_expiration(ldns_key *k, uint32_t e);
-/**
- * Set the key's pubkey owner
- * \param[in] k the key
- * \param[in] r the owner
- */
-void ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r);
-/**
- * Set the key's key tag
- * \param[in] k the key
- * \param[in] tag the keytag
- */
-void ldns_key_set_keytag(ldns_key *k, uint16_t tag);
-/**
- * Set the key's flags
- * \param[in] k the key
- * \param[in] flags the flags
- */
-void ldns_key_set_flags(ldns_key *k, uint16_t flags);
-/**
- * Set the keylist's key count to count
- * \param[in] key the key
- * \param[in] count the cuont
- */
-void ldns_key_list_set_key_count(ldns_key_list *key, size_t count);
-
-/**     
- * pushes a key to a keylist
- * \param[in] key_list the key_list to push to 
- * \param[in] key the key to push 
- * \return false on error, otherwise true
- */      
-bool ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key);
-
-/**
- * returns the number of keys in the key list
- * \param[in] key_list the key_list
- * \return the numbers of keys in the list
- */
-size_t ldns_key_list_key_count(const ldns_key_list *key_list);
-
-/**
- * returns a pointer to the key in the list at the given position
- * \param[in] key the key
- * \param[in] nr the position in the list
- * \return the key
- */
-ldns_key *ldns_key_list_key(const ldns_key_list *key, size_t nr);
-
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-/**
- * returns the (openssl) RSA struct contained in the key
- * \param[in] k the key to look in
- * \return the RSA * structure in the key
- */
-RSA *ldns_key_rsa_key(const ldns_key *k);
-/**
- * returns the (openssl) EVP struct contained in the key
- * \param[in] k the key to look in
- * \return the RSA * structure in the key
- */
-EVP_PKEY *ldns_key_evp_key(const ldns_key *k);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-/**
- * returns the (openssl) DSA struct contained in the key
- */
-#if LDNS_BUILD_CONFIG_HAVE_SSL
-DSA *ldns_key_dsa_key(const ldns_key *k);
-#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
-
-/**
- * return the signing alg of the key
- * \param[in] k the key
- * \return the algorithm
- */
-ldns_signing_algorithm ldns_key_algorithm(const ldns_key *k);
-/**
- * set the use flag
- * \param[in] k the key
- * \param[in] v the boolean value to set the _use field to
- */
-void ldns_key_set_use(ldns_key *k, bool v);
-/**
- * return the use flag
- * \param[in] k the key
- * \return the boolean value of the _use field
- */
-bool ldns_key_use(const ldns_key *k);
-/**
- * return the hmac key data
- * \param[in] k the key
- * \return the hmac key data
- */
-unsigned char *ldns_key_hmac_key(const ldns_key *k);
-/**
- * return the key id key data
- * \param[in] k the key
- * \return the key id data
- */
-void *ldns_key_external_key(const ldns_key *k);
-/**
- * return the hmac key size
- * \param[in] k the key
- * \return the hmac key size
- */
-size_t ldns_key_hmac_size(const ldns_key *k);
-/**
- * return the original ttl of the key
- * \param[in] k the key
- * \return the original ttl
- */
-uint32_t ldns_key_origttl(const ldns_key *k);
-/**
- * return the key's inception date
- * \param[in] k the key
- * \return the inception date
- */
-uint32_t ldns_key_inception(const ldns_key *k);
-/**
- * return the key's expiration date
- * \param[in] k the key
- * \return the experiration date
- */
-uint32_t ldns_key_expiration(const ldns_key *k);
-/**
- * return the keytag
- * \param[in] k the key
- * \return the keytag
- */
-uint16_t ldns_key_keytag(const ldns_key *k);
-/**
- * return the public key's owner
- * \param[in] k the key
- * \return the owner
- */
-ldns_rdf *ldns_key_pubkey_owner(const ldns_key *k);
-/**
- * Set the 'use' flag for all keys in the list
- * \param[in] keys The key_list
- * \param[in] v The value to set the use flags to
- */
-void
-ldns_key_list_set_use(ldns_key_list *keys, bool v);
-
-/**
- * return the flag of the key
- * \param[in] k the key
- * \return the flag
- */
-uint16_t ldns_key_flags(const ldns_key *k);
-
-/**     
- * pops the last rr from a keylist
- * \param[in] key_list the rr_list to pop from
- * \return NULL if nothing to pop. Otherwise the popped RR
- */
-ldns_key *ldns_key_list_pop_key(ldns_key_list *key_list);
-
-/** 
- * converts a ldns_key to a public key rr
- * If the key data exists at an external point, the corresponding
- * rdata field must still be added with ldns_rr_rdf_push() to the
- * result rr of this function
- *
- * \param[in] k the ldns_key to convert
- * \return ldns_rr representation of the key
- */
-ldns_rr *ldns_key2rr(const ldns_key *k);
-
-/**
- * print a private key to the file ouput
- * 
- * \param[in] output the FILE descriptor where to print to
- * \param[in] k the ldns_key to print
- */
-void ldns_key_print(FILE *output, const ldns_key *k);
-
-/**
- * frees a key structure, but not its internal data structures
- *
- * \param[in] key the key object to free
- */
-void ldns_key_free(ldns_key *key);
-
-/**
- * frees a key structure and all its internal data structures, except
- * the data set by ldns_key_set_external_key()
- *
- * \param[in] key the key object to free
- */
-void ldns_key_deep_free(ldns_key *key);
-
-/**
- * Frees a key list structure
- * \param[in] key_list the key list object to free
- */
-void ldns_key_list_free(ldns_key_list *key_list);
-
-/**
- * Instantiates a DNSKEY or DS RR from file.
- * \param[in] filename the file to read the record from
- * \return the corresponding RR, or NULL if the parsing failed
- */
-ldns_rr * ldns_read_anchor_file(const char *filename);
-
-/**
- * Returns the 'default base name' for key files;
- * IE. K\<zone\>+\<alg\>+\<keytag\>
- * (without the .key or .private)
- * The memory for this is allocated by this function,
- * and should be freed by the caller
- * 
- * \param[in] key the key to get the file name from
- * \returns A string containing the file base name
- */
-char *ldns_key_get_file_base_name(ldns_key *key);
-
-/**
- * See if a key algorithm is supported
- * \param[in] algo the signing algorithm number.
- * \returns true if supported.
- */
-int ldns_key_algo_supported(int algo);
-
-/**
- * Get signing algorithm by name.  Comparison is case insensitive.
- * \param[in] name string with the name.
- * \returns 0 on parse failure or the algorithm number.
- */
-ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_KEYS_H */
diff --git a/include/ldns/ldns.h b/include/ldns/ldns.h
deleted file mode 100644
index 60663ef..0000000
--- a/include/ldns/ldns.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * dns.h -- defines for the Domain Name System
- *
- * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- *
- * This library was created by:
- * Jelte Jansen, Erik Rozendaal and Miek Gieben
- *
- * A bunch of defines that are used in the DNS.
- */
-
-
-/**
-\mainpage LDNS Documentation
-
-\section introduction Introduction
-
-The goal of ldns is to simplify DNS programming, it supports recent RFCs
-like the DNSSEC documents, and allow developers to easily create software
-conforming to current RFCs, and experimental software for current Internet
-drafts. A secondary benefit of using ldns is speed, because ldns is written
-in C, and although it is not optimized for performance, it should be a lot
-faster than Perl.
-
-The first main tool to use ldns is Drill, from which part of the library was
-derived. From version 1.0.0 on, drill is included in the ldns release
-and will not be distributed separately anymore. The library also includes some
-other examples and tools to show how it can be used. These can be found in the
-examples/ directory in the tarball.
-
-ldns depends on OpenSSL for it's cryptographic functions.
-Feature list
-
-  - Transparent IPv4 and IPv6 support (overridable if necessary),
-  - TSIG support,
-  - DNSSEC support; signing and verification,
-  - small size,
-  - online documentation as well as manual pages.
-
-If you want to send us patches please use the code from git.
-
-\section using_ldns Using ldns
-
-Almost all interaction between an application and ldns goes through the ldns
-data structures (\ref ldns_rr, \ref ldns_pkt, etc.). These are input or
-output to the functions of ldns. For example, \ref ldns_zone_new_frm_fp
-reads a zone from a \c FILE pointer, and returns an \ref ldns_zone
-structure.
-
-
-Let's use Drill as an example. Drill is a tool much like dig, whose most
-basic function is to send 1 query to a nameserver and print the response.
-
-To be able to do this, drill uses the resolver module of ldns, which acts as
-a stub resolver. The resolver module uses the net module to actually send
-the query that drill requested. It then uses the wire2host module to
-translate the response and place it in ldns' internal structures. These are
-passed back to drill, which then uses the host2str module to print the
-response in presentation format.
-
-\section gettingstarted Getting Started
-
-See the \ref design page for a very high level description of the design
-choices made for ldns. 
-
-For an overview of the functions and types ldns provides, you can check out
-the \ref ldns ldns header file descriptions.
-
-If you want to see some libdns action, you can read our tutorials:
-  - \ref tutorial1_mx
-  - \ref tutorial2_zone
-  - \ref tutorial3_signzone
-
-Or you can just use the menu above to browse through the API docs.
-
-<div style="visibility:hidden;">
-\image html LogoInGradientBar2-y100.png
-</div>
-*/
-
-/**
- * \file ldns.h
- *
- * Including this file will include all ldns files, and define some lookup tables.
- */
-
-#ifndef LDNS_DNS_H
-#define LDNS_DNS_H
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <ldns/util.h>
-#include <ldns/buffer.h>
-#include <ldns/common.h>
-#include <ldns/dane.h>
-#include <ldns/dname.h>
-#include <ldns/dnssec.h>
-#include <ldns/dnssec_verify.h>
-#include <ldns/dnssec_sign.h>
-#include <ldns/duration.h>
-#include <ldns/error.h>
-#include <ldns/higher.h>
-#include <ldns/host2str.h>
-#include <ldns/host2wire.h>
-#include <ldns/net.h>
-#include <ldns/packet.h>
-#include <ldns/rdata.h>
-#include <ldns/resolver.h>
-#include <ldns/rr.h>
-#include <ldns/str2host.h>
-#include <ldns/tsig.h>
-#include <ldns/update.h>
-#include <ldns/wire2host.h>
-#include <ldns/rr_functions.h>
-#include <ldns/keys.h>
-#include <ldns/parse.h>
-#include <ldns/zone.h>
-#include <ldns/dnssec_zone.h>
-#include <ldns/radix.h>
-#include <ldns/rbtree.h>
-#include <ldns/sha1.h>
-#include <ldns/sha2.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LDNS_IP4ADDRLEN      (32/8)
-#define LDNS_IP6ADDRLEN      (128/8)
-#define LDNS_PORT	53
-#define LDNS_ROOT_LABEL_STR     "."
-#define LDNS_DEFAULT_TTL	3600
-
-/* lookup tables for standard DNS stuff  */
-
-/** Taken from RFC 2538, section 2.1.  */
-extern ldns_lookup_table ldns_certificate_types[];
-/** Taken from RFC 2535, section 7.  */
-extern ldns_lookup_table ldns_algorithms[];
-/** Taken from RFC 2538.  */
-extern ldns_lookup_table ldns_cert_algorithms[];
-/** rr types  */
-extern ldns_lookup_table ldns_rr_classes[];
-/** Response codes */
-extern ldns_lookup_table ldns_rcodes[];
-/** Operation codes */
-extern ldns_lookup_table ldns_opcodes[];
-/** EDNS flags */
-extern ldns_lookup_table ldns_edns_flags[];
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_DNS_H */
diff --git a/include/ldns/net.h b/include/ldns/net.h
deleted file mode 100644
index 692a9fb..0000000
--- a/include/ldns/net.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * net.h
- *
- * DNS Resolver definitions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-#ifndef LDNS_NET_H
-#define LDNS_NET_H
-
-#include <ldns/ldns.h>
-#include <sys/socket.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LDNS_DEFAULT_TIMEOUT_SEC 5
-#define LDNS_DEFAULT_TIMEOUT_USEC 0
-
-/**
- * \file
- *
- * Contains functions to send and receive packets over a network.
- */
-
-/**
- * Sends a buffer to an ip using udp and return the respons as a ldns_pkt
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] to the ip addr to send to
- * \param[in] tolen length of the ip addr
- * \param[in] timeout the timeout value for the network
- * \param[out] answersize size of the packet
- * \param[out] result packet with the answer
- * \return status
- */
-ldns_status ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answersize);
-
-/**
- * Send an udp query and don't wait for an answer but return
- * the socket
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] to the ip addr to send to
- * \param[in] tolen length of the ip addr
- * \param[in] timeout *unused*, was the timeout value for the network
- * \return the socket used
- */
-int ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
-
-/**
- * Send an tcp query and don't wait for an answer but return
- * the socket
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] to the ip addr to send to
- * \param[in] tolen length of the ip addr
- * \param[in] timeout the timeout value for the connect attempt
- * \return the socket used
- */
-int ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
-
-/**
- * Sends a buffer to an ip using tcp and return the respons as a ldns_pkt
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] qbin the ldns_buffer to be send
- * \param[in] to the ip addr to send to
- * \param[in] tolen length of the ip addr
- * \param[in] timeout the timeout value for the network
- * \param[out] answersize size of the packet
- * \param[out] result packet with the answer
- * \return status
- */
-ldns_status ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answersize);
-
-/**
- * Sends ptk to the nameserver at the resolver object. Returns the data
- * as a ldns_pkt
- * 
- * \param[out] pkt packet received from the nameserver
- * \param[in] r the resolver to use 
- * \param[in] query_pkt the query to send
- * \return status
- */
-ldns_status ldns_send(ldns_pkt **pkt, ldns_resolver *r, const ldns_pkt *query_pkt);
-
-/**
- * Sends and ldns_buffer (presumably containing a packet to the nameserver at the resolver object. Returns the data
- * as a ldns_pkt
- * 
- * \param[out] pkt packet received from the nameserver
- * \param[in] r the resolver to use 
- * \param[in] qb the buffer to send
- * \param[in] tsig_mac the tsig MAC to authenticate the response with (NULL to do no TSIG authentication)
- * \return status
- */
-ldns_status ldns_send_buffer(ldns_pkt **pkt, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac);
-
-/**
- * Create a tcp socket to the specified address
- * \param[in] to ip and family
- * \param[in] tolen length of to
- * \param[in] timeout timeout for the connect attempt
- * \return a socket descriptor
- */
-int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
-
-/**
- * Create a udp socket to the specified address
- * \param[in] to ip and family
- * \param[in] timeout *unused*, was timeout for the socket
- * \return a socket descriptor
- */
-int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout);
-
-/**
- * send a query via tcp to a server. Don't want for the answer
- *
- * \param[in] qbin the buffer to send
- * \param[in] sockfd the socket to use
- * \param[in] to which ip to send it
- * \param[in] tolen socketlen
- * \return number of bytes sent
- */
-ssize_t ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
-
-/**
- * send a query via udp to a server. Don;t want for the answer
- *
- * \param[in] qbin the buffer to send
- * \param[in] sockfd the socket to use
- * \param[in] to which ip to send it
- * \param[in] tolen socketlen
- * \return number of bytes sent
- */
-ssize_t ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
-
-/**
- * Gives back a raw packet from the wire and reads the header data from the given
- * socket. Allocates the data (of size size) itself, so don't forget to free
- *
- * \param[in] sockfd the socket to read from
- * \param[out] size the number of bytes that are read
- * \param[in] timeout the time allowed between packets.
- * \return the data read
- */
-uint8_t *ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout);
-
-/**
- * This routine may block. Use ldns_tcp_read_wire_timeout, it checks timeouts.
- * Gives back a raw packet from the wire and reads the header data from the given
- * socket. Allocates the data (of size size) itself, so don't forget to free
- *
- * \param[in] sockfd the socket to read from
- * \param[out] size the number of bytes that are read
- * \return the data read
- */
-uint8_t *ldns_tcp_read_wire(int sockfd, size_t *size);
-
-/**
- * Gives back a raw packet from the wire and reads the header data from the given
- * socket. Allocates the data (of size size) itself, so don't forget to free
- *
- * \param[in] sockfd the socket to read from
- * \param[in] fr the address of the client (if applicable)
- * \param[in] *frlen the lenght of the client's addr (if applicable)
- * \param[out] size the number of bytes that are read
- * \return the data read
- */
-uint8_t *ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *fr, socklen_t *frlen);
-
-/**
- * returns the native sockaddr representation from the rdf.
- * \param[in] rd the ldns_rdf to operate on
- * \param[in] port what port to use. 0 means; use default (53)
- * \param[out] size what is the size of the sockaddr_storage
- * \return struct sockaddr* the address in the format so other
- * functions can use it (sendto)
- */
-struct sockaddr_storage * ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size);
-
-/**
- * returns an rdf with the sockaddr info. works for ip4 and ip6
- * \param[in] sock the struct sockaddr_storage to convert
- * \param[in] port what port was used. When NULL this is not set
- * \return ldns_rdf* wth the address
- */
-ldns_rdf * ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port);
-
-/**
- * Prepares the resolver for an axfr query
- * The query is sent and the answers can be read with ldns_axfr_next
- * \param[in] resolver the resolver to use
- * \param[in] domain the domain to exfr
- * \param[in] c the class to use
- * \return ldns_status the status of the transfer
- */
-ldns_status ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class c);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* LDNS_NET_H */
diff --git a/include/ldns/packet.h b/include/ldns/packet.h
deleted file mode 100644
index e66aa34..0000000
--- a/include/ldns/packet.h
+++ /dev/null
@@ -1,891 +0,0 @@
-/*
- * packet.h
- *
- * DNS packet definitions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file
- *
- * Contains the definition of ldns_pkt and its parts, as well
- * as functions to manipulate those.
- */
-
-
-#ifndef LDNS_PACKET_H
-#define LDNS_PACKET_H
-
-#define LDNS_MAX_PACKETLEN         65535
-
-/* allow flags to be given to mk_query */
-#define LDNS_QR		1       /* QueRy - query flag */
-#define LDNS_AA		2       /* Authoritative Answer - server flag */
-#define LDNS_TC		4       /* TrunCated - server flag */
-#define LDNS_RD		8       /* Recursion Desired - query flag */
-#define LDNS_CD		16      /* Checking Disabled - query flag */
-#define LDNS_RA		32      /* Recursion Available - server flag */
-#define LDNS_AD		64      /* Authenticated Data - server flag */
-
-#include <ldns/error.h>
-#include <ldns/common.h>
-#include <ldns/rr.h>
-#include <sys/time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* opcodes for pkt's */
-enum ldns_enum_pkt_opcode {
-	LDNS_PACKET_QUERY = 0,
-	LDNS_PACKET_IQUERY = 1,
-	LDNS_PACKET_STATUS = 2, /* there is no 3?? DNS is weird */
-	LDNS_PACKET_NOTIFY = 4,
-	LDNS_PACKET_UPDATE = 5
-};
-typedef enum ldns_enum_pkt_opcode ldns_pkt_opcode;
-
-/* rcodes for pkts */
-enum ldns_enum_pkt_rcode {
-	LDNS_RCODE_NOERROR = 0,
-	LDNS_RCODE_FORMERR = 1,
-	LDNS_RCODE_SERVFAIL = 2,
-	LDNS_RCODE_NXDOMAIN = 3,
-	LDNS_RCODE_NOTIMPL = 4,
-	LDNS_RCODE_REFUSED = 5,
-	LDNS_RCODE_YXDOMAIN = 6,
-	LDNS_RCODE_YXRRSET = 7,
-	LDNS_RCODE_NXRRSET = 8,
-	LDNS_RCODE_NOTAUTH = 9,
-	LDNS_RCODE_NOTZONE = 10
-};
-typedef enum ldns_enum_pkt_rcode ldns_pkt_rcode;
-
-/**
- *  Header of a dns packet
- *
- * Contains the information about the packet itself, as specified in RFC1035
-<pre>
-4.1.1. Header section format
-
-The header contains the following fields:
-
-                                    1  1  1  1  1  1
-      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                      ID                       |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                    QDCOUNT                    |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                    ANCOUNT                    |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                    NSCOUNT                    |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                    ARCOUNT                    |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-
-where:
-
-ID              A 16 bit identifier assigned by the program that
-                generates any kind of query.  This identifier is copied
-                the corresponding reply and can be used by the requester
-                to match up replies to outstanding queries.
-
-QR              A one bit field that specifies whether this message is a
-                query (0), or a response (1).
-
-OPCODE          A four bit field that specifies kind of query in this
-                message.  This value is set by the originator of a query
-                and copied into the response.  The values are:
-
-                0               a standard query (QUERY)
-
-                1               an inverse query (IQUERY)
-
-                2               a server status request (STATUS)
-
-                3-15            reserved for future use
-
-AA              Authoritative Answer - this bit is valid in responses,
-                and specifies that the responding name server is an
-                authority for the domain name in question section.
-
-                Note that the contents of the answer section may have
-                multiple owner names because of aliases.  The AA bit
-
-                corresponds to the name which matches the query name, or
-                the first owner name in the answer section.
-
-TC              TrunCation - specifies that this message was truncated
-                due to length greater than that permitted on the
-                transmission channel.
-
-RD              Recursion Desired - this bit may be set in a query and
-                is copied into the response.  If RD is set, it directs
-                the name server to pursue the query recursively.
-                Recursive query support is optional.
-
-RA              Recursion Available - this be is set or cleared in a
-                response, and denotes whether recursive query support is
-                available in the name server.
-
-Z               Reserved for future use.  Must be zero in all queries
-                and responses.
-
-RCODE           Response code - this 4 bit field is set as part of
-                responses.  The values have the following
-                interpretation:
-
-                0               No error condition
-
-                1               Format error - The name server was
-                                unable to interpret the query.
-
-                2               Server failure - The name server was
-                                unable to process this query due to a
-                                problem with the name server.
-
-                3               Name Error - Meaningful only for
-                                responses from an authoritative name
-                                server, this code signifies that the
-                                domain name referenced in the query does
-                                not exist.
-
-                4               Not Implemented - The name server does
-                                not support the requested kind of query.
-
-                5               Refused - The name server refuses to
-                                perform the specified operation for
-                                policy reasons.  For example, a name
-                                server may not wish to provide the
-                                information to the particular requester,
-                                or a name server may not wish to perform
-                                a particular operation (e.g., zone
-
-                                transfer) for particular data.
-
-                6-15            Reserved for future use.
-
-QDCOUNT         an unsigned 16 bit integer specifying the number of
-                entries in the question section.
-
-ANCOUNT         an unsigned 16 bit integer specifying the number of
-                resource records in the answer section.
-
-NSCOUNT         an unsigned 16 bit integer specifying the number of name
-                server resource records in the authority records
-                section.
-
-ARCOUNT         an unsigned 16 bit integer specifying the number of
-                resource records in the additional records section.
-
-</pre>
- */
-struct ldns_struct_hdr
-{
-	/**  Id of a packet */
-	uint16_t _id;
-	/**  Query bit (0=query, 1=answer) */
-	bool _qr;
-	/**  Authoritative answer */
-	bool _aa;
-	/**  Packet truncated */
-	bool _tc;
-	/**  Recursion desired */
-	bool _rd;
-	/**  Checking disabled */
-	bool _cd;
-	/**  Recursion available */
-	bool _ra;
-	/**  Authentic data */
-	bool _ad;
-	/**  Query type */
-	ldns_pkt_opcode _opcode;	 /* XXX 8 bits? */
-	/**  Response code */
-	uint8_t _rcode;
-	/**  question sec */
-	uint16_t _qdcount;
-	/**  answer sec */
-	uint16_t _ancount;
-	/**  auth sec */
-	uint16_t _nscount;
-	/**  add sec */
-	uint16_t _arcount;
-};
-typedef struct ldns_struct_hdr ldns_hdr;
-
-/**
- * DNS packet
- *
- * This structure contains a complete DNS packet (either a query or an answer)
- *
- * It is the complete representation of what you actually send to a
- * nameserver, and what it sends back (assuming you are the client here).
- */
-struct ldns_struct_pkt
-{
-	/** Header section */
-	ldns_hdr *_header;
-	/* extra items needed in a packet */
-	/** The size of the wire format of the packet in octets */
-	ldns_rdf *_answerfrom;
-        /** Timestamp of the time the packet was sent or created */
-	struct timeval timestamp;
-	/** The duration of the query this packet is an answer to */
-	uint32_t _querytime;
-	/** The size of the wire format of the packet in octets */
-	size_t _size;
-	/** Optional tsig rr */
-	ldns_rr *_tsig_rr;
-	/** EDNS0 available buffer size, see RFC2671 */
-	uint16_t _edns_udp_size;
-	/** EDNS0 Extended rcode */
-	uint8_t _edns_extended_rcode;
-	/** EDNS Version */
-	uint8_t _edns_version;
-        /* OPT pseudo-RR presence flag */
-        uint8_t _edns_present;
-	/** Reserved EDNS data bits */
-	uint16_t _edns_z;
-	/** Arbitrary EDNS rdata */
-	ldns_rdf *_edns_data;
-	/**  Question section */
-	ldns_rr_list	*_question;
-	/**  Answer section */
-	ldns_rr_list	*_answer;
-	/**  Authority section */
-	ldns_rr_list	*_authority;
-	/**  Additional section */
-	ldns_rr_list	*_additional;
-};
-typedef struct ldns_struct_pkt ldns_pkt;
-
-/**
- * The sections of a packet
- */
-enum ldns_enum_pkt_section {
-	LDNS_SECTION_QUESTION = 0,
-	LDNS_SECTION_ANSWER = 1,
-	LDNS_SECTION_AUTHORITY = 2,
-	LDNS_SECTION_ADDITIONAL = 3,
-	/** bogus section, if not interested */
-	LDNS_SECTION_ANY = 4,
-	/** used to get all non-question rrs from a packet */
-	LDNS_SECTION_ANY_NOQUESTION = 5
-};
-typedef enum ldns_enum_pkt_section ldns_pkt_section;	
-
-/**
- * The different types of packets
- */
-enum ldns_enum_pkt_type {
-	LDNS_PACKET_QUESTION,
-	LDNS_PACKET_REFERRAL,
-	LDNS_PACKET_ANSWER,
-	LDNS_PACKET_NXDOMAIN,
-	LDNS_PACKET_NODATA,
-	LDNS_PACKET_UNKNOWN
-};
-typedef enum ldns_enum_pkt_type ldns_pkt_type;
-
-/* prototypes */
-
-/* read */
-
-/**
- * Read the packet id
- * \param[in] p the packet
- * \return the packet id
- */
-uint16_t ldns_pkt_id(const ldns_pkt *p);
-/**
- * Read the packet's qr bit
- * \param[in] p the packet
- * \return value of the bit
- */
-bool ldns_pkt_qr(const ldns_pkt *p);
-/**
- * Read the packet's aa bit
- * \param[in] p the packet
- * \return value of the bit
- */
-bool ldns_pkt_aa(const ldns_pkt *p);
-/**
- * Read the packet's tc bit
- * \param[in] p the packet
- * \return value of the bit
- */
-bool ldns_pkt_tc(const ldns_pkt *p);
-/**
- * Read the packet's rd bit
- * \param[in] p the packet
- * \return value of the bit
- */
-bool ldns_pkt_rd(const ldns_pkt *p);
-/**
- * Read the packet's cd bit
- * \param[in] p the packet
- * \return value of the bit
- */
-bool ldns_pkt_cd(const ldns_pkt *p);
-/**
- * Read the packet's ra bit
- * \param[in] p the packet
- * \return value of the bit
- */
-bool ldns_pkt_ra(const ldns_pkt *p);
-/**
- * Read the packet's ad bit
- * \param[in] p the packet
- * \return value of the bit
- */
-bool ldns_pkt_ad(const ldns_pkt *p);
-/**
- * Read the packet's code
- * \param[in] p the packet
- * \return the opcode
- */
-ldns_pkt_opcode ldns_pkt_get_opcode(const ldns_pkt *p);
-/**
- * Return the packet's respons code
- * \param[in] p the packet
- * \return the respons code
- */
-ldns_pkt_rcode ldns_pkt_get_rcode(const ldns_pkt *p);
-/**
- * Return the packet's qd count 
- * \param[in] p the packet
- * \return the qd count
- */
-uint16_t ldns_pkt_qdcount(const ldns_pkt *p);
-/**
- * Return the packet's an count
- * \param[in] p the packet
- * \return the an count
- */
-uint16_t ldns_pkt_ancount(const ldns_pkt *p);
-/**
- * Return the packet's ns count
- * \param[in] p the packet
- * \return the ns count
- */
-uint16_t ldns_pkt_nscount(const ldns_pkt *p);
-/**
- * Return the packet's ar count
- * \param[in] p the packet
- * \return the ar count
- */
-uint16_t ldns_pkt_arcount(const ldns_pkt *p);
-
-/** 
- * Return the packet's answerfrom
- * \param[in] p packet
- * \return the name of the server
- */
-ldns_rdf *ldns_pkt_answerfrom(const ldns_pkt *p);
-
-/**
- * Return the packet's timestamp
- * \param[in] p the packet
- * \return the timestamp
- */
-struct timeval ldns_pkt_timestamp(const ldns_pkt *p);
-/**
- * Return the packet's querytime
- * \param[in] p the packet
- * \return the querytime
- */
-uint32_t ldns_pkt_querytime(const ldns_pkt *p);
-
-/**
- * Return the packet's size in bytes
- * \param[in] p the packet
- * \return the size
- */
-size_t ldns_pkt_size(const ldns_pkt *p);
-
-/**
- * Return the number of RRs in the given section.
- * Returns the sum of all RRs when LDNS_SECTION_ANY is given.
- * Returns the sum of all non-question RRs when LDNS_SECTION_ANY_NOQUESTION
- * is given.
- * \param[in] p the packet
- * \param[in] s the section
- * \return the number of RRs in the given section
- */
-uint16_t ldns_pkt_section_count(const ldns_pkt *p, ldns_pkt_section s);
-
-/**
- * Return the packet's tsig pseudo rr's
- * \param[in] p the packet
- * \return the tsig rr
- */
-ldns_rr *ldns_pkt_tsig(const ldns_pkt *p);
-
-/**
- * Return the packet's question section
- * \param[in] p the packet
- * \return the section
- */
-ldns_rr_list *ldns_pkt_question(const ldns_pkt *p);
-/**
- * Return the packet's answer section
- * \param[in] p the packet
- * \return the section
- */
-ldns_rr_list *ldns_pkt_answer(const ldns_pkt *p);
-/**
- * Return the packet's authority section
- * \param[in] p the packet
- * \return the section
- */
-ldns_rr_list *ldns_pkt_authority(const ldns_pkt *p);
-/**
- * Return the packet's additional section
- * \param[in] p the packet
- * \return the section
- */
-ldns_rr_list *ldns_pkt_additional(const ldns_pkt *p);
-/**
- * Return the packet's question, answer, authority and additional sections
- * concatenated, in a new rr_list clone.
- * \param[in] p the packet
- * \return the rrs
- */
-ldns_rr_list *ldns_pkt_all(const ldns_pkt *p);
-/**
- * Return the packet's answer, authority and additional sections concatenated, 
- * in a new rr_list clone.  Like ldns_pkt_all but without the questions.
- * \param[in] p the packet
- * \return the rrs except the question rrs
- */
-ldns_rr_list *ldns_pkt_all_noquestion(const ldns_pkt *p);
-
-/**
- * return all the rr_list's in the packet. Clone the lists, instead
- * of returning pointers. 
- * \param[in] p the packet to look in
- * \param[in] s what section(s) to return
- * \return ldns_rr_list with the rr's or NULL if none were found
- */
-ldns_rr_list *ldns_pkt_get_section_clone(const ldns_pkt *p, ldns_pkt_section s);
-
-/**
- * return all the rr with a specific name from a packet. Optionally
- * specify from which section in the packet
- * \param[in] p the packet
- * \param[in] r the name
- * \param[in] s the packet's section
- * \return a list with the rr's or NULL if none were found
- */
-ldns_rr_list *ldns_pkt_rr_list_by_name(ldns_pkt *p, ldns_rdf *r, ldns_pkt_section s);
-/**
- * return all the rr with a specific type from a packet. Optionally
- * specify from which section in the packet
- * \param[in] p the packet
- * \param[in] t the type
- * \param[in] s the packet's section
- * \return a list with the rr's or NULL if none were found
- */
-ldns_rr_list *ldns_pkt_rr_list_by_type(const ldns_pkt *p, ldns_rr_type t, ldns_pkt_section s);
-/**
- * return all the rr with a specific type and type from a packet. Optionally
- * specify from which section in the packet
- * \param[in] packet the packet
- * \param[in] ownername the name
- * \param[in] type the type
- * \param[in] sec the packet's section
- * \return a list with the rr's or NULL if none were found
- */
-ldns_rr_list *ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet, const ldns_rdf *ownername, ldns_rr_type type, ldns_pkt_section sec);
-
-
-/**
- * check to see if an rr exist in the packet
- * \param[in] pkt the packet to examine
- * \param[in] sec in which section to look
- * \param[in] rr the rr to look for
- */
-bool ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr);
-
-
-/**
- * sets the flags in a packet.
- * \param[in] pkt the packet to operate on
- * \param[in] flags ORed values: LDNS_QR| LDNS_AR for instance
- * \return true on success otherwise false
- */
-bool ldns_pkt_set_flags(ldns_pkt *pkt, uint16_t flags);
-
-/**
- * Set the packet's id
- * \param[in] p the packet
- * \param[in] id the id to set
- */
-void ldns_pkt_set_id(ldns_pkt *p, uint16_t id);
-/**
- * Set the packet's id to a random value
- * \param[in] p the packet
- */
-void ldns_pkt_set_random_id(ldns_pkt *p);
-/**
- * Set the packet's qr bit
- * \param[in] p the packet
- * \param[in] b the value to set (boolean)
- */
-void ldns_pkt_set_qr(ldns_pkt *p, bool b);
-/**
- * Set the packet's aa bit
- * \param[in] p the packet
- * \param[in] b the value to set (boolean)
- */
-void ldns_pkt_set_aa(ldns_pkt *p, bool b);
-/**
- * Set the packet's tc bit
- * \param[in] p the packet
- * \param[in] b the value to set (boolean)
- */
-void ldns_pkt_set_tc(ldns_pkt *p, bool b);
-/**
- * Set the packet's rd bit
- * \param[in] p the packet
- * \param[in] b the value to set (boolean)
- */
-void ldns_pkt_set_rd(ldns_pkt *p, bool b);
-/**
- * Set the packet's cd bit
- * \param[in] p the packet
- * \param[in] b the value to set (boolean)
- */
-void ldns_pkt_set_cd(ldns_pkt *p, bool b);
-/**
- * Set the packet's ra bit
- * \param[in] p the packet
- * \param[in] b the value to set (boolean)
- */
-void ldns_pkt_set_ra(ldns_pkt *p, bool b);
-/**
- * Set the packet's ad bit
- * \param[in] p the packet
- * \param[in] b the value to set (boolean)
- */
-void ldns_pkt_set_ad(ldns_pkt *p, bool b);
-
-/**
- * Set the packet's opcode
- * \param[in] p the packet
- * \param[in] c the opcode
- */
-void ldns_pkt_set_opcode(ldns_pkt *p, ldns_pkt_opcode c);
-/**
- * Set the packet's respons code
- * \param[in] p the packet
- * \param[in] c the rcode
- */
-void ldns_pkt_set_rcode(ldns_pkt *p, uint8_t c);
-/**
- * Set the packet's qd count
- * \param[in] p the packet
- * \param[in] c the count
- */
-void ldns_pkt_set_qdcount(ldns_pkt *p, uint16_t c);
-/**
- * Set the packet's an count
- * \param[in] p the packet
- * \param[in] c the count
- */
-void ldns_pkt_set_ancount(ldns_pkt *p, uint16_t c);
-/**
- * Set the packet's ns count
- * \param[in] p the packet
- * \param[in] c the count
- */
-void ldns_pkt_set_nscount(ldns_pkt *p, uint16_t c);
-/**
- * Set the packet's arcount
- * \param[in] p the packet
- * \param[in] c the count
- */
-void ldns_pkt_set_arcount(ldns_pkt *p, uint16_t c);
-/**
- * Set the packet's answering server
- * \param[in] p the packet
- * \param[in] r the address
- */
-void ldns_pkt_set_answerfrom(ldns_pkt *p, ldns_rdf *r);
-/**
- * Set the packet's query time
- * \param[in] p the packet
- * \param[in] t the querytime in msec
- */
-void ldns_pkt_set_querytime(ldns_pkt *p, uint32_t t);
-/**
- * Set the packet's size
- * \param[in] p the packet
- * \param[in] s the size
- */
-void ldns_pkt_set_size(ldns_pkt *p, size_t s);
-
-/**
- * Set the packet's timestamp
- * \param[in] p the packet
- * \param[in] timeval the timestamp
- */
-void ldns_pkt_set_timestamp(ldns_pkt *p, struct timeval timeval);
-/**
- * Set a packet's section count to x
- * \param[in] p the packet
- * \param[in] s the section
- * \param[in] x the section count
- */
-void ldns_pkt_set_section_count(ldns_pkt *p, ldns_pkt_section s, uint16_t x);
-/**
- * Set the packet's tsig rr
- * \param[in] p the packet
- * \param[in] t the tsig rr
- */
-void ldns_pkt_set_tsig(ldns_pkt *p, ldns_rr *t);
-
-/**
- * looks inside the packet to determine
- * what kind of packet it is, AUTH, NXDOMAIN, REFERRAL, etc.
- * \param[in] p the packet to examine
- * \return the type of packet
- */
-ldns_pkt_type ldns_pkt_reply_type(ldns_pkt *p);
-
-/**
- * return the packet's edns udp size
- * \param[in] packet the packet
- * \return the size
- */
-uint16_t ldns_pkt_edns_udp_size(const ldns_pkt *packet);
-/**
- * return the packet's edns extended rcode
- * \param[in] packet the packet
- * \return the rcode
- */
-uint8_t ldns_pkt_edns_extended_rcode(const ldns_pkt *packet);
-/**
- * return the packet's edns version
- * \param[in] packet the packet
- * \return the version
- */
-uint8_t ldns_pkt_edns_version(const ldns_pkt *packet);
-/**
- * return the packet's edns z value
- * \param[in] packet the packet
- * \return the z value
- */
-uint16_t ldns_pkt_edns_z(const ldns_pkt *packet);
-/**
- * return the packet's edns data
- * \param[in] packet the packet
- * \return the data
- */
-ldns_rdf *ldns_pkt_edns_data(const ldns_pkt *packet);
-
-/**
- * return the packet's edns do bit
- * \param[in] packet the packet
- * \return the bit's value
- */
-bool ldns_pkt_edns_do(const ldns_pkt *packet);
-/**
- * Set the packet's edns do bit
- * \param[in] packet the packet
- * \param[in] value the bit's new value
- */
-void ldns_pkt_set_edns_do(ldns_pkt *packet, bool value);
-
-/**
- * returns true if this packet needs and EDNS rr to be sent.
- * At the moment the only reason is an expected packet
- * size larger than 512 bytes, but for instance dnssec would
- * be a good reason too.
- *
- * \param[in] packet the packet to check
- * \return true if packet needs edns rr
- */
-bool ldns_pkt_edns(const ldns_pkt *packet);
-
-/**
- * Set the packet's edns udp size
- * \param[in] packet the packet
- * \param[in] s the size
- */
-void ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s);
-/**
- * Set the packet's edns extended rcode
- * \param[in] packet the packet
- * \param[in] c the code
- */
-void ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c);
-/**
- * Set the packet's edns version
- * \param[in] packet the packet
- * \param[in] v the version
- */
-void ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v);
-/**
- * Set the packet's edns z value
- * \param[in] packet the packet
- * \param[in] z the value
- */
-void ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z);
-/**
- * Set the packet's edns data
- * \param[in] packet the packet
- * \param[in] data the data
- */
-void ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data);
-
-/**
- * allocates and initializes a ldns_pkt structure.
- * \return pointer to the new packet
- */
-ldns_pkt *ldns_pkt_new(void);
-
-/**
- * frees the packet structure and all data that it contains.
- * \param[in] packet The packet structure to free
- * \return void
- */
-void ldns_pkt_free(ldns_pkt *packet);
-
-/**
- * creates a query packet for the given name, type, class.
- * \param[out] p the packet to be returned
- * \param[in] rr_name the name to query for (as string)
- * \param[in] rr_type the type to query for
- * \param[in] rr_class the class to query for
- * \param[in] flags packet flags
- * \return LDNS_STATUS_OK or a ldns_status mesg with the error
- */
-ldns_status ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class , uint16_t flags);
-
-/**
- * creates an IXFR request packet for the given name, class.
- * adds the SOA record to the authority section.
- * \param[out] p the packet to be returned
- * \param[in] rr_name the name to query for (as string)
- * \param[in] rr_class the class to query for
- * \param[in] flags packet flags
- * \param[in] soa soa record to be added to the authority section
- * \return LDNS_STATUS_OK or a ldns_status mesg with the error
- */
-ldns_status ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *rr_name, ldns_rr_class rr_class, uint16_t flags, ldns_rr* soa);
-
-/**
- * creates a packet with a query in it for the given name, type and class.
- * \param[in] rr_name the name to query for
- * \param[in] rr_type the type to query for
- * \param[in] rr_class the class to query for
- * \param[in] flags packet flags
- * \return ldns_pkt* a pointer to the new pkt
- */
-ldns_pkt *ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags);
-
-/**
- * creates an IXFR request packet for the given name, type and class.
- * adds the SOA record to the authority section.
- * \param[in] rr_name the name to query for
- * \param[in] rr_class the class to query for
- * \param[in] flags packet flags
- * \param[in] soa soa record to be added to the authority section
- * \return ldns_pkt* a pointer to the new pkt
- */
-ldns_pkt *ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class, uint16_t flags, ldns_rr* soa);
-
-/**
- * clones the given packet, creating a fully allocated copy
- *
- * \param[in] pkt the packet to clone
- * \return ldns_pkt* pointer to the new packet
- */
-ldns_pkt *ldns_pkt_clone(const ldns_pkt *pkt);
-
-/**
- * directly set the additional section
- * \param[in] p packet to operate on
- * \param[in] rr rrlist to set
- */
-void ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr);
-
-/**
- * directly set the answer section
- * \param[in] p packet to operate on
- * \param[in] rr rrlist to set
- */
-void ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr);
-
-/**
- * directly set the question section
- * \param[in] p packet to operate on
- * \param[in] rr rrlist to set
- */
-void ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr);
-
-/**
- * directly set the auhority section
- * \param[in] p packet to operate on
- * \param[in] rr rrlist to set
- */
-void ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr);
-
-/**
- * push an rr on a packet
- * \param[in] packet packet to operate on
- * \param[in] section where to put it
- * \param[in] rr rr to push
- * \return a boolean which is true when the rr was added
- */
-bool ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr);
-
-/**
- * push an rr on a packet, provided the RR is not there.
- * \param[in] pkt packet to operate on
- * \param[in] sec where to put it
- * \param[in] rr rr to push
- * \return a boolean which is true when the rr was added
- */
-bool ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr);
-
-/**
- * push a rr_list on a packet
- * \param[in] packet packet to operate on
- * \param[in] section where to put it
- * \param[in] list the rr_list to push
- * \return a boolean which is true when the rr was added
- */
-bool ldns_pkt_push_rr_list(ldns_pkt *packet, ldns_pkt_section section, ldns_rr_list *list);
-
-/**
- * push an rr_list to a packet, provided the RRs are not already there.
- * \param[in] pkt packet to operate on
- * \param[in] sec where to put it
- * \param[in] list the rr_list to push
- * \return a boolean which is true when the rr was added
- */
-bool ldns_pkt_safe_push_rr_list(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr_list *list);
-
-/**
- * check if a packet is empty
- * \param[in] p packet
- * \return true: empty, false: not empty
- */
-bool ldns_pkt_empty(ldns_pkt *p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* LDNS_PACKET_H */
diff --git a/include/ldns/parse.h b/include/ldns/parse.h
deleted file mode 100644
index 0e9034c..0000000
--- a/include/ldns/parse.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * parse.h 
- *
- * a Net::DNS like library for C
- * LibDNS Team @ NLnet Labs
- * (c) NLnet Labs, 2005-2006
- * See the file LICENSE for the license
- */
-
-#ifndef LDNS_PARSE_H
-#define LDNS_PARSE_H
-
-#include <ldns/common.h>
-#include <ldns/buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LDNS_PARSE_SKIP_SPACE		"\f\n\r\v"
-#define LDNS_PARSE_NORMAL		" \f\n\r\t\v"
-#define LDNS_PARSE_NO_NL		" \t"
-#define LDNS_MAX_LINELEN		10230
-#define LDNS_MAX_KEYWORDLEN		32
-
-
-/**
- * \file
- *
- * Contains some low-level parsing functions, mostly used in the _frm_str
- * family of functions.
- */
- 
-/**
- * different type of directives in zone files
- * We now deal with $TTL, $ORIGIN and $INCLUDE.
- * The latter is not implemented in ldns (yet)
- */
-enum ldns_enum_directive
-{
-	LDNS_DIR_TTL,
-	LDNS_DIR_ORIGIN,
-	LDNS_DIR_INCLUDE
-};
-typedef enum ldns_enum_directive ldns_directive;
-
-/** 
- * returns a token/char from the stream F.
- * This function deals with ( and ) in the stream,
- * and ignores them when encountered
- * \param[in] *f the file to read from
- * \param[out] *token the read token is put here
- * \param[in] *delim chars at which the parsing should stop
- * \param[in] *limit how much to read. If 0 the builtin maximum is used
- * \return 0 on error of EOF of the stream F.  Otherwise return the length of what is read
- */
-ssize_t ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit);
-
-/** 
- * returns a token/char from the stream F.
- * This function deals with ( and ) in the stream,
- * and ignores when it finds them.
- * \param[in] *f the file to read from
- * \param[out] *token the token is put here
- * \param[in] *delim chars at which the parsing should stop
- * \param[in] *limit how much to read. If 0 use builtin maximum
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return 0 on error of EOF of F otherwise return the length of what is read
- */
-ssize_t ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr);
-
-/**
- * returns a token/char from the buffer b.
- * This function deals with ( and ) in the buffer,
- * and ignores when it finds them.
- * \param[in] *b the buffer to read from
- * \param[out] *token the token is put here
- * \param[in] *delim chars at which the parsing should stop
- * \param[in] *limit how much to read. If 0 the builtin maximum is used
- * \returns 0 on error of EOF of b. Otherwise return the length of what is read
- */
-ssize_t ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit);
-
-/*
- * searches for keyword and delim in a file. Gives everything back
- * after the keyword + k_del until we hit d_del
- * \param[in] f file pointer to read from
- * \param[in] keyword keyword to look for
- * \param[in] k_del keyword delimeter 
- * \param[out] data the data found 
- * \param[in] d_del the data delimeter
- * \param[in] data_limit maximum size the the data buffer
- * \return the number of character read
- */
-ssize_t ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
-
-/*
- * searches for keyword and delim. Gives everything back
- * after the keyword + k_del until we hit d_del
- * \param[in] f file pointer to read from
- * \param[in] keyword keyword to look for
- * \param[in] k_del keyword delimeter 
- * \param[out] data the data found 
- * \param[in] d_del the data delimeter
- * \param[in] data_limit maximum size the the data buffer
- * \param[in] line_nr pointer to an integer containing the current line number (for
-debugging purposes)
- * \return the number of character read
- */
-ssize_t ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit, int *line_nr);
-
-/*
- * searches for keyword and delim in a buffer. Gives everything back
- * after the keyword + k_del until we hit d_del
- * \param[in] b buffer pointer to read from
- * \param[in] keyword keyword to look for
- * \param[in] k_del keyword delimeter 
- * \param[out] data the data found 
- * \param[in] d_del the data delimeter
- * \param[in] data_limit maximum size the the data buffer
- * \return the number of character read
- */
-ssize_t ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
-
-/**
- * returns the next character from a buffer. Advances the position pointer with 1.
- * When end of buffer is reached returns EOF. This is the buffer's equivalent
- * for getc().
- * \param[in] *buffer buffer to read from
- * \return EOF on failure otherwise return the character
- */
-int ldns_bgetc(ldns_buffer *buffer);
-
-/**
- * skips all of the characters in the given string in the buffer, moving
- * the position to the first character that is not in *s.
- * \param[in] *buffer buffer to use
- * \param[in] *s characters to skip
- * \return void
- */
-void ldns_bskipcs(ldns_buffer *buffer, const char *s);
-
-/**
- * skips all of the characters in the given string in the fp, moving
- * the position to the first character that is not in *s.
- * \param[in] *fp file to use
- * \param[in] *s characters to skip
- * \return void
- */
-void ldns_fskipcs(FILE *fp, const char *s);
-
-
-/**
- * skips all of the characters in the given string in the fp, moving
- * the position to the first character that is not in *s.
- * \param[in] *fp file to use
- * \param[in] *s characters to skip
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return void
- */
-void ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_PARSE_H */
diff --git a/include/ldns/radix.h b/include/ldns/radix.h
deleted file mode 100644
index 1885959..0000000
--- a/include/ldns/radix.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * radix.h -- generic radix tree
- *
- * Copyright (c) 2012, NLnet Labs. All rights reserved.
- *
- * This software is open source.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NLNET LABS nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * \file
- * Radix tree. Implementation taken from NSD 4, adjusted for use in ldns.
- *
- */
-
-#ifndef LDNS_RADIX_H_
-#define	LDNS_RADIX_H_
-
-#include <ldns/error.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef uint16_t radix_strlen_t;
-typedef struct ldns_radix_array_t ldns_radix_array_t;
-typedef struct ldns_radix_node_t ldns_radix_node_t;
-typedef struct ldns_radix_t ldns_radix_t;
-
-/** Radix node select edge array */
-struct ldns_radix_array_t {
-	/** Additional string after the selection byte for this edge. */
-	uint8_t* str;
-	/** Length of additional string for this edge. */
-	radix_strlen_t len;
-	/** Node that deals with byte+str. */
-	ldns_radix_node_t* edge;
-};
-
-/** A node in a radix tree */
-struct ldns_radix_node_t {
-	/** Key corresponding to this node. */
-	uint8_t* key;
-	/** Key length corresponding to this node. */
-	radix_strlen_t klen;
-	/** Data corresponding to this node. */
-	void* data;
-	/** Parent node. */
-	ldns_radix_node_t* parent;
-	/** Index in the the parent node select edge array. */
-	uint8_t parent_index;
-	/** Length of the array. */
-	uint16_t len;
-	/** Offset of the array. */
-	uint16_t offset;
-	/** Capacity of the array. */
-	uint16_t capacity;
-	/** Select edge array. */
-	ldns_radix_array_t* array;
-};
-
-/** An entire radix tree */
-struct ldns_radix_t {
-	/** Root. */
-	ldns_radix_node_t* root;
-	/** Number of nodes in tree. */
-	size_t count;
-};
-
-/**
- * Create a new radix tree.
- * @return: new radix tree.
- *
- */
-ldns_radix_t* ldns_radix_create(void);
-
-/**
- * Initialize radix tree.
- * @param tree: uninitialized radix tree.
- *
- */
-void ldns_radix_init(ldns_radix_t* tree);
-
-/**
- * Free the radix tree.
- * @param tree: radix tree.
- *
- */
-void ldns_radix_free(ldns_radix_t* tree);
-
-/**
- * Insert data into the tree.
- * @param tree: tree to insert to.
- * @param key:  key.
- * @param len:  length of key.
- * @param data: data.
- * @return: status.
- *
- */
-ldns_status ldns_radix_insert(ldns_radix_t* tree, uint8_t* key,
-	radix_strlen_t len, void* data);
-
-/**
- * Delete data from the tree.
- * @param tree: tree to insert to.
- * @param key:  key.
- * @param len:  length of key.
- * @return: unlinked data or NULL if not present.
- *
- */
-void* ldns_radix_delete(ldns_radix_t* tree, uint8_t* key, radix_strlen_t len);
-
-/**
- * Search data in the tree.
- * @param tree: tree to insert to.
- * @param key:  key.
- * @param len:  length of key.
- * @return: the radix node or NULL if not found.
- *
- */
-ldns_radix_node_t* ldns_radix_search(ldns_radix_t* tree, uint8_t* key,
-	radix_strlen_t len);
-
-/**
- * Search data in the tree, and if not found, find the closest smaller
- * element in the tree.
- * @param tree: tree to insert to.
- * @param key:  key.
- * @param len:  length of key.
- * @param result: the radix node with the exact or closest match. NULL if
- *                the key is smaller than the smallest key in the tree.
- * @return 1 if exact match, 0 otherwise.
- *
- */
-int ldns_radix_find_less_equal(ldns_radix_t* tree, uint8_t* key,
-	radix_strlen_t len, ldns_radix_node_t** result);
-
-/**
- * Get the first element in the tree.
- * @param tree: tree.
- * @return: the radix node with the first element.
- *
- */
-ldns_radix_node_t* ldns_radix_first(ldns_radix_t* tree);
-
-/**
- * Get the last element in the tree.
- * @param tree: tree.
- * @return: the radix node with the last element.
- *
- */
-ldns_radix_node_t* ldns_radix_last(ldns_radix_t* tree);
-
-/**
- * Next element.
- * @param node: node.
- * @return: node with next element.
- *
- */
-ldns_radix_node_t* ldns_radix_next(ldns_radix_node_t* node);
-
-/**
- * Previous element.
- * @param node: node.
- * @return: node with previous element.
- *
- */
-ldns_radix_node_t* ldns_radix_prev(ldns_radix_node_t* node);
-
-/**
- * Split radix tree intwo.
- * @param tree1: one tree.
- * @param num: number of elements to split off.
- * @param tree2: another tree.
- * @return: status.
- *
- */
-ldns_status ldns_radix_split(ldns_radix_t* tree1, size_t num,
-	ldns_radix_t** tree2);
-
-/**
- * Join two radix trees.
- * @param tree1: one tree.
- * @param tree2: another tree.
- * @return: status.
- *
- */
-ldns_status ldns_radix_join(ldns_radix_t* tree1, ldns_radix_t* tree2);
-
-/**
- * Call function for all nodes in the tree, such that leaf nodes are
- * called before parent nodes.
- * @param node: start node.
- * @param func: function.
- * @param arg: user argument.
- *
- */
-void ldns_radix_traverse_postorder(ldns_radix_node_t* node,
-        void (*func)(ldns_radix_node_t*, void*), void* arg);
-
-/**
- * Print radix tree (for debugging purposes).
- * @param fd: file descriptor.
- * @param tree: tree.
- *
- */
-void ldns_radix_printf(FILE* fd, ldns_radix_t* tree);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_RADIX_H_ */
diff --git a/include/ldns/rbtree.h b/include/ldns/rbtree.h
deleted file mode 100644
index c891934..0000000
--- a/include/ldns/rbtree.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * rbtree.h -- generic red-black tree
- *
- * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
- *
- * This software is open source.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NLNET LABS nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * \file
- * Red black tree. Implementation taken from NSD 3.0.5, adjusted for use
- * in unbound (memory allocation, logging and so on).
- */
-
-#ifndef LDNS_RBTREE_H_
-#define	LDNS_RBTREE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * This structure must be the first member of the data structure in
- * the rbtree.  This allows easy casting between an rbnode_t and the
- * user data (poor man's inheritance).
- * Or you can use the data pointer member to get to your data item.
- */
-typedef struct ldns_rbnode_t ldns_rbnode_t;
-/**
- * The rbnode_t struct definition.
- */
-struct ldns_rbnode_t {
-	/** parent in rbtree, RBTREE_NULL for root */
-	ldns_rbnode_t   *parent;
-	/** left node (smaller items) */
-	ldns_rbnode_t   *left;
-	/** right node (larger items) */
-	ldns_rbnode_t   *right;
-	/** pointer to sorting key */
-	const void *key;
-	/** pointer to data */
-	const void *data;
-	/** colour of this node */
-	uint8_t	    color;
-};
-
-/** The nullpointer, points to empty node */
-#define	LDNS_RBTREE_NULL &ldns_rbtree_null_node
-/** the global empty node */
-extern	ldns_rbnode_t	ldns_rbtree_null_node;
-
-/** An entire red black tree */
-typedef struct ldns_rbtree_t ldns_rbtree_t;
-/** definition for tree struct */
-struct ldns_rbtree_t {
-	/** The root of the red-black tree */
-	ldns_rbnode_t    *root;
-
-	/** The number of the nodes in the tree */
-	size_t       count;
-
-	/**
-	 * Key compare function. <0,0,>0 like strcmp.
-	 * Return 0 on two NULL ptrs.
-	 */
-	int (*cmp) (const void *, const void *);
-};
-
-/**
- * Create new tree (malloced) with given key compare function.
- * @param cmpf: compare function (like strcmp) takes pointers to two keys.
- * @return: new tree, empty.
- */
-ldns_rbtree_t *ldns_rbtree_create(int (*cmpf)(const void *, const void *));
-
-/**
- * Free the complete tree (but not its keys)
- * @param rbtree The tree to free
- */
-void ldns_rbtree_free(ldns_rbtree_t *rbtree);
-
-/**
- * Init a new tree (malloced by caller) with given key compare function.
- * @param rbtree: uninitialised memory for new tree, returned empty.
- * @param cmpf: compare function (like strcmp) takes pointers to two keys.
- */
-void ldns_rbtree_init(ldns_rbtree_t *rbtree, int (*cmpf)(const void *, const void *));
-
-/**
- * Insert data into the tree.
- * @param rbtree: tree to insert to.
- * @param data: element to insert.
- * @return: data ptr or NULL if key already present.
- */
-ldns_rbnode_t *ldns_rbtree_insert(ldns_rbtree_t *rbtree, ldns_rbnode_t *data);
-
-/**
- * Insert data into the tree (reversed arguments, for use as callback)
- * \param[in] data element to insert
- * \param[out] rbtree tree to insert in to
- * \return data ptr or NULL if key is already present
- */
-void ldns_rbtree_insert_vref(ldns_rbnode_t *data, void *rbtree);
-
-/**
- * Delete element from tree.
- * @param rbtree: tree to delete from.
- * @param key: key of item to delete.
- * @return: node that is now unlinked from the tree. User to delete it.
- * returns 0 if node not present
- */
-ldns_rbnode_t *ldns_rbtree_delete(ldns_rbtree_t *rbtree, const void *key);
-
-/**
- * Find key in tree. Returns NULL if not found.
- * @param rbtree: tree to find in.
- * @param key: key that must match.
- * @return: node that fits or NULL.
- */
-ldns_rbnode_t *ldns_rbtree_search(ldns_rbtree_t *rbtree, const void *key);
-
-/**
- * Find, but match does not have to be exact.
- * @param rbtree: tree to find in.
- * @param key: key to find position of.
- * @param result: set to the exact node if present, otherwise to element that
- *   precedes the position of key in the tree. NULL if no smaller element.
- * @return: true if exact match in result. Else result points to <= element,
- * or NULL if key is smaller than the smallest key.
- */
-int ldns_rbtree_find_less_equal(ldns_rbtree_t *rbtree, const void *key,
-	ldns_rbnode_t **result);
-
-/**
- * Returns first (smallest) node in the tree
- * @param rbtree: tree
- * @return: smallest element or NULL if tree empty.
- */
-ldns_rbnode_t *ldns_rbtree_first(ldns_rbtree_t *rbtree);
-
-/**
- * Returns last (largest) node in the tree
- * @param rbtree: tree
- * @return: largest element or NULL if tree empty.
- */
-ldns_rbnode_t *ldns_rbtree_last(ldns_rbtree_t *rbtree);
-
-/**
- * Returns next larger node in the tree
- * @param rbtree: tree
- * @return: next larger element or NULL if no larger in tree.
- */
-ldns_rbnode_t *ldns_rbtree_next(ldns_rbnode_t *rbtree);
-
-/**
- * Returns previous smaller node in the tree
- * @param rbtree: tree
- * @return: previous smaller element or NULL if no previous in tree.
- */
-ldns_rbnode_t *ldns_rbtree_previous(ldns_rbnode_t *rbtree);
-
-/**
- * split off 'elements' number of elements from the start
- * of the name tree and return a new tree containing those
- * elements
- */
-ldns_rbtree_t *ldns_rbtree_split(ldns_rbtree_t *tree, size_t elements);
-
-/**
- * add all node from the second tree to the first (removing them from the
- * second), and fix up nsec(3)s if present
- */
-void ldns_rbtree_join(ldns_rbtree_t *tree1, ldns_rbtree_t *tree2);
-
-/**
- * Call with node=variable of struct* with rbnode_t as first element.
- * with type is the type of a pointer to that struct.
- */
-#define LDNS_RBTREE_FOR(node, type, rbtree) \
-	for(node=(type)ldns_rbtree_first(rbtree); \
-		(ldns_rbnode_t*)node != LDNS_RBTREE_NULL; \
-		node = (type)ldns_rbtree_next((ldns_rbnode_t*)node))
-
-/**
- * Call function for all elements in the redblack tree, such that
- * leaf elements are called before parent elements. So that all
- * elements can be safely free()d.
- * Note that your function must not remove the nodes from the tree.
- * Since that may trigger rebalances of the rbtree.
- * @param tree: the tree
- * @param func: function called with element and user arg.
- * 	The function must not alter the rbtree.
- * @param arg: user argument.
- */
-void ldns_traverse_postorder(ldns_rbtree_t* tree,
-	void (*func)(ldns_rbnode_t*, void*), void* arg);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* UTIL_RBTREE_H_ */
diff --git a/include/ldns/rdata.h b/include/ldns/rdata.h
deleted file mode 100644
index 22665b1..0000000
--- a/include/ldns/rdata.h
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * rdata.h
- *
- * rdata definitions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-
-/**
- * \file
- *
- * Defines ldns_rdf and functions to manipulate those.
- */
-
-
-#ifndef LDNS_RDATA_H
-#define LDNS_RDATA_H
-
-#include <ldns/common.h>
-#include <ldns/error.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define LDNS_MAX_RDFLEN	65535
-
-#define LDNS_RDF_SIZE_BYTE              1
-#define LDNS_RDF_SIZE_WORD              2
-#define LDNS_RDF_SIZE_DOUBLEWORD        4
-#define LDNS_RDF_SIZE_6BYTES            6
-#define LDNS_RDF_SIZE_8BYTES            8
-#define LDNS_RDF_SIZE_16BYTES           16
-
-#define LDNS_NSEC3_VARS_OPTOUT_MASK 0x01
-
-/**
- * The different types of RDATA fields.
- */
-enum ldns_enum_rdf_type
-{
-	/** none */
-	LDNS_RDF_TYPE_NONE,
-	/** domain name */
-	LDNS_RDF_TYPE_DNAME,
-	/** 8 bits */
-	LDNS_RDF_TYPE_INT8,
-	/** 16 bits */
-	LDNS_RDF_TYPE_INT16,
-	/** 32 bits */
-	LDNS_RDF_TYPE_INT32,
-	/** A record */
-	LDNS_RDF_TYPE_A,
-	/** AAAA record */
-	LDNS_RDF_TYPE_AAAA,
-	/** txt string */
-	LDNS_RDF_TYPE_STR,
-	/** apl data */
-	LDNS_RDF_TYPE_APL,
-	/** b32 string */
-	LDNS_RDF_TYPE_B32_EXT,
-	/** b64 string */
-	LDNS_RDF_TYPE_B64,
-	/** hex string */
-	LDNS_RDF_TYPE_HEX,
-	/** nsec type codes */
-	LDNS_RDF_TYPE_NSEC,
-	/** a RR type */
-	LDNS_RDF_TYPE_TYPE,
-	/** a class */
-	LDNS_RDF_TYPE_CLASS,
-	/** certificate algorithm */
-	LDNS_RDF_TYPE_CERT_ALG,
-	/** a key algorithm */
-	LDNS_RDF_TYPE_ALG,
-	/** unknown types */
-	LDNS_RDF_TYPE_UNKNOWN,
-	/** time (32 bits) */
-	LDNS_RDF_TYPE_TIME,
-	/** period */
-	LDNS_RDF_TYPE_PERIOD,
-	/** tsig time 48 bits */
-	LDNS_RDF_TYPE_TSIGTIME,
-	/** Represents the Public Key Algorithm, HIT and Public Key fields
-	    for the HIP RR types.  A HIP specific rdf type is used because of
-	    the unusual layout in wireformat (see RFC 5205 Section 5) */
-	LDNS_RDF_TYPE_HIP,
-	/** variable length any type rdata where the length
-	    is specified by the first 2 bytes */
-	LDNS_RDF_TYPE_INT16_DATA,
-	/** protocol and port bitmaps */
-	LDNS_RDF_TYPE_SERVICE,
-	/** location data */
-	LDNS_RDF_TYPE_LOC,
-	/** well known services */
-	LDNS_RDF_TYPE_WKS,
-	/** NSAP */
-	LDNS_RDF_TYPE_NSAP,
-	/** ATMA */
-	LDNS_RDF_TYPE_ATMA,
-	/** IPSECKEY */
-	LDNS_RDF_TYPE_IPSECKEY,
-	/** nsec3 hash salt */
-	LDNS_RDF_TYPE_NSEC3_SALT,
-	/** nsec3 base32 string (with length byte on wire */
-	LDNS_RDF_TYPE_NSEC3_NEXT_OWNER,
-
-	/** 4 shorts represented as 4 * 16 bit hex numbers
-	 *  separated by colons. For NID and L64.
-	 */
-	LDNS_RDF_TYPE_ILNP64,
-
-	/** 6 * 8 bit hex numbers separated by dashes. For EUI48. */
-	LDNS_RDF_TYPE_EUI48,
-	/** 8 * 8 bit hex numbers separated by dashes. For EUI64. */
-	LDNS_RDF_TYPE_EUI64,
-
-	/** A non-zero sequence of US-ASCII letters and numbers in lower case.
-	 *  For CAA.
-	 */
-	LDNS_RDF_TYPE_TAG,
-
-	/** A <character-string> encoding of the value field as specified 
-	 * [RFC1035], Section 5.1., encoded as remaining rdata.
-	 * For CAA.
-	 */
-	LDNS_RDF_TYPE_LONG_STR,
-
-	/** Since RFC7218 TLSA records can be given with mnemonics,
-	 * hence these rdata field types.  But as with DNSKEYs, the output
-	 * is always numeric.
-	 */
-	LDNS_RDF_TYPE_CERTIFICATE_USAGE,
-	LDNS_RDF_TYPE_SELECTOR,
-	LDNS_RDF_TYPE_MATCHING_TYPE,
-
-	/* Aliases */
-	LDNS_RDF_TYPE_BITMAP = LDNS_RDF_TYPE_NSEC
-};
-typedef enum ldns_enum_rdf_type ldns_rdf_type;
-
-/**
- * algorithms used in CERT rrs
- */
-enum ldns_enum_cert_algorithm
-{
-        LDNS_CERT_PKIX		= 1,
-        LDNS_CERT_SPKI		= 2,
-        LDNS_CERT_PGP		= 3,
-        LDNS_CERT_IPKIX         = 4,
-        LDNS_CERT_ISPKI         = 5,
-        LDNS_CERT_IPGP          = 6,
-        LDNS_CERT_ACPKIX        = 7,
-        LDNS_CERT_IACPKIX       = 8,
-        LDNS_CERT_URI		= 253,
-        LDNS_CERT_OID		= 254
-};
-typedef enum ldns_enum_cert_algorithm ldns_cert_algorithm;
-
-
-
-/**
- * Resource record data field.
- *
- * The data is a network ordered array of bytes, which size is specified by
- * the (16-bit) size field. To correctly parse it, use the type
- * specified in the (16-bit) type field with a value from \ref ldns_rdf_type.
- */
-struct ldns_struct_rdf
-{
-	/** The size of the data (in octets) */
-	size_t _size;
-	/** The type of the data */
-	ldns_rdf_type _type;
-	/** Pointer to the data (raw octets) */
-	void  *_data;
-};
-typedef struct ldns_struct_rdf ldns_rdf;
-
-/* prototypes */
-
-/* write access functions */
-
-/**
- * sets the size of the rdf.
- * \param[in] *rd the rdf to operate on
- * \param[in] size the new size
- * \return void
- */
-void ldns_rdf_set_size(ldns_rdf *rd, size_t size);
-
-/**
- * sets the size of the rdf.
- * \param[in] *rd the rdf to operate on
- * \param[in] type the new type
- * \return void
- */
-void ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type);
-
-/**
- * sets the size of the rdf.
- * \param[in] *rd the rdf to operate on
- * \param[in] *data pointer to the new data
- * \return void
- */
-void ldns_rdf_set_data(ldns_rdf *rd, void *data);
-
-/* read access */
-
-/**
- * returns the size of the rdf.
- * \param[in] *rd the rdf to read from
- * \return uint16_t with the size
- */
-size_t ldns_rdf_size(const ldns_rdf *rd);
-
-/**
- * returns the type of the rdf. We need to insert _get_
- * here to prevent conflict the the rdf_type TYPE.
- * \param[in] *rd the rdf to read from
- * \return ldns_rdf_type with the type
- */
-ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd);
-
-/**
- * returns the data of the rdf.
- * \param[in] *rd the rdf to read from
- *
- * \return uint8_t* pointer to the rdf's data
- */
-uint8_t *ldns_rdf_data(const ldns_rdf *rd);
-
-/* creator functions */
-
-/**
- * allocates a new rdf structure and fills it.
- * This function DOES NOT copy the contents from
- * the buffer, unlinke ldns_rdf_new_frm_data()
- * \param[in] type type of the rdf
- * \param[in] size size of the buffer
- * \param[in] data pointer to the buffer to be copied
- * \return the new rdf structure or NULL on failure
- */
-ldns_rdf *ldns_rdf_new(ldns_rdf_type type, size_t size, void *data);
-
-/**
- * allocates a new rdf structure and fills it.
- * This function _does_ copy the contents from
- * the buffer, unlinke ldns_rdf_new()
- * \param[in] type type of the rdf
- * \param[in] size size of the buffer
- * \param[in] data pointer to the buffer to be copied
- * \return the new rdf structure or NULL on failure
- */
-ldns_rdf *ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data);
-
-/**
- * creates a new rdf from a string.
- * \param[in] type   type to use
- * \param[in] str string to use
- * \return ldns_rdf* or NULL in case of an error
- */
-ldns_rdf *ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str);
-
-/**
- * creates a new rdf from a file containing a string.
- * \param[out] r the new rdf
- * \param[in] type   type to use
- * \param[in] fp the file pointer  to use
- * \return LDNS_STATUS_OK or the error
- */
-ldns_status ldns_rdf_new_frm_fp(ldns_rdf **r, ldns_rdf_type type, FILE *fp);
-
-/**
- * creates a new rdf from a file containing a string.
- * \param[out] r the new rdf
- * \param[in] type   type to use
- * \param[in] fp the file pointer  to use
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return LDNS_STATUS_OK or the error
- */
-ldns_status ldns_rdf_new_frm_fp_l(ldns_rdf **r, ldns_rdf_type type, FILE *fp, int *line_nr);
-
-/* destroy functions */
-
-/**
- * frees a rdf structure, leaving the
- * data pointer intact.
- * \param[in] rd the pointer to be freed
- * \return void
- */
-void ldns_rdf_free(ldns_rdf *rd);
-
-/**
- * frees a rdf structure _and_ frees the
- * data. rdf should be created with _new_frm_data
- * \param[in] rd the rdf structure to be freed
- * \return void
- */
-void ldns_rdf_deep_free(ldns_rdf *rd);
-
-/* conversion functions */
-
-/**
- * returns the rdf containing the native uint8_t repr.
- * \param[in] type the ldns_rdf type to use
- * \param[in] value the uint8_t to use
- * \return ldns_rdf* with the converted value
- */
-ldns_rdf *ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value);
-
-/**
- * returns the rdf containing the native uint16_t representation.
- * \param[in] type the ldns_rdf type to use
- * \param[in] value the uint16_t to use
- * \return ldns_rdf* with the converted value
- */
-ldns_rdf *ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value);
-
-/**
- * returns an rdf that contains the given int32 value.
- *
- * Because multiple rdf types can contain an int32, the
- * type must be specified
- * \param[in] type the ldns_rdf type to use
- * \param[in] value the uint32_t to use
- * \return ldns_rdf* with the converted value
- */
-ldns_rdf *ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value);
-
-/**
- * returns an int16_data rdf that contains the data in the
- * given array, preceded by an int16 specifying the length.
- *
- * The memory is copied, and an LDNS_RDF_TYPE_INT16DATA is returned
- * \param[in] size the size of the data
- * \param[in] *data pointer to the actual data
- *
- * \return ldns_rd* the rdf with the data
- */
-ldns_rdf *ldns_native2rdf_int16_data(size_t size, uint8_t *data);
-
-/**
- * reverses an rdf, only actually useful for AAAA and A records.
- * The returned rdf has the type LDNS_RDF_TYPE_DNAME!
- * \param[in] *rd rdf to be reversed
- * \return the reversed rdf (a newly created rdf)
- */
-ldns_rdf *ldns_rdf_address_reverse(ldns_rdf *rd);
-
-/**
- * returns the native uint8_t representation from the rdf.
- * \param[in] rd the ldns_rdf to operate on
- * \return uint8_t the value extracted
- */
-uint8_t 	ldns_rdf2native_int8(const ldns_rdf *rd);
-
-/**
- * returns the native uint16_t representation from the rdf.
- * \param[in] rd the ldns_rdf to operate on
- * \return uint16_t the value extracted
- */
-uint16_t	ldns_rdf2native_int16(const ldns_rdf *rd);
-
-/**
- * returns the native uint32_t representation from the rdf.
- * \param[in] rd the ldns_rdf to operate on
- * \return uint32_t the value extracted
- */
-uint32_t ldns_rdf2native_int32(const ldns_rdf *rd);
-
-/**
- * returns the native time_t representation from the rdf.
- * \param[in] rd the ldns_rdf to operate on
- * \return time_t the value extracted (32 bits currently)
- */
-time_t ldns_rdf2native_time_t(const ldns_rdf *rd);
-
-/**
- * converts a ttl value (like 5d2h) to a long.
- * \param[in] nptr the start of the string
- * \param[out] endptr points to the last char in case of error
- * \return the convert duration value
- */
-uint32_t ldns_str2period(const char *nptr, const char **endptr);
-
-/**
- * removes \\DDD, \\[space] and other escapes from the input.
- * See RFC 1035, section 5.1.
- * \param[in] word what to check
- * \param[in] length the string
- * \return ldns_status mesg
- */
-ldns_status ldns_octet(char *word, size_t *length);
-
-/**
- * clones a rdf structure. The data is copied.
- * \param[in] rd rdf to be copied
- * \return a new rdf structure
- */
-ldns_rdf *ldns_rdf_clone(const ldns_rdf *rd);
-
-/**
- * compares two rdf's on their wire formats.
- * (To order dnames according to rfc4034, use ldns_dname_compare)
- * \param[in] rd1 the first one
- * \param[in] rd2 the second one
- * \return 0 if equal
- * \return -1 if rd1 comes before rd2
- * \return +1 if rd2 comes before rd1
- */
-int ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2);
-
-/**
- * Gets the algorithm value, the HIT and Public Key data from the rdf with
- * type LDNS_RDF_TYPE_HIP.
- * \param[in] rdf the rdf with type LDNS_RDF_TYPE_HIP
- * \param[out] alg      the algorithm
- * \param[out] hit_size the size of the HIT data
- * \param[out] hit      the hit data
- * \param[out] pk_size  the size of the Public Key data
- * \param[out] pk       the  Public Key data
- * \return LDNS_STATUS_OK on success, and the error otherwise
- */
-ldns_status ldns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg,
-		uint8_t *hit_size, uint8_t** hit,
-		uint16_t *pk_size, uint8_t** pk);
-
-/**
- * Creates a new LDNS_RDF_TYPE_HIP rdf from given data.
- * \param[out] rdf      the newly created LDNS_RDF_TYPE_HIP rdf
- * \param[in]  alg      the algorithm
- * \param[in]  hit_size the size of the HIT data
- * \param[in]  hit      the hit data
- * \param[in]  pk_size  the size of the Public Key data
- * \param[in]  pk       the  Public Key data
- * \return LDNS_STATUS_OK on success, and the error otherwise
- */
-ldns_status ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf** rdf, uint8_t alg,
-		uint8_t hit_size, uint8_t *hit, uint16_t pk_size, uint8_t *pk);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif	/* LDNS_RDATA_H */
diff --git a/include/ldns/resolver.h b/include/ldns/resolver.h
deleted file mode 100644
index 228485c..0000000
--- a/include/ldns/resolver.h
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * resolver.h
- *
- * DNS Resolver definitions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file
- *
- * Defines the  ldns_resolver structure, a stub resolver that can send queries and parse answers.
- *
- */
-
-#ifndef LDNS_RESOLVER_H
-#define LDNS_RESOLVER_H
-
-#include <ldns/error.h>
-#include <ldns/common.h>
-#include <ldns/rr.h>
-#include <ldns/tsig.h>
-#include <ldns/rdata.h>
-#include <ldns/packet.h>
-#include <sys/time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Default location of the resolv.conf file */
-#define LDNS_RESOLV_CONF	"/etc/resolv.conf"
-/** Default location of the hosts file */
-#define LDNS_RESOLV_HOSTS	"/etc/hosts"
-
-#define LDNS_RESOLV_KEYWORD     -1
-#define LDNS_RESOLV_DEFDOMAIN	0
-#define LDNS_RESOLV_NAMESERVER	1
-#define LDNS_RESOLV_SEARCH	2
-#define LDNS_RESOLV_SORTLIST	3
-#define LDNS_RESOLV_OPTIONS	4
-#define LDNS_RESOLV_ANCHOR	5
-#define LDNS_RESOLV_KEYWORDS    6
-
-#define LDNS_RESOLV_INETANY		0
-#define LDNS_RESOLV_INET		1
-#define LDNS_RESOLV_INET6		2
-
-#define LDNS_RESOLV_RTT_INF             0       /* infinity */
-#define LDNS_RESOLV_RTT_MIN             1       /* reachable */
-
-/**
- * DNS stub resolver structure
- */
-struct ldns_struct_resolver
-{
-	/**  Port to send queries to */
-	uint16_t _port;
-
-	/** Array of nameservers to query (IP addresses or dnames) */
-	ldns_rdf **_nameservers;
-	/** Number of nameservers in \c _nameservers */
-	size_t _nameserver_count; /* how many do we have */
-
-	/**  Round trip time; 0 -> infinity. Unit: ms? */
-	size_t *_rtt;
-
-	/**  Whether or not to be recursive */
-	bool _recursive;
-
-	/**  Print debug information */
-	bool _debug;
-
-	/**  Default domain to add to non fully qualified domain names */
-	ldns_rdf *_domain;
-
-	/**  Searchlist array, add the names in this array if a query cannot be found */
-	ldns_rdf **_searchlist;
-
-	/** Number of entries in the searchlist array */
-	size_t _searchlist_count;
-
-	/**  Number of times to retry before giving up */
-	uint8_t _retry;
-	/**  Time to wait before retrying */
-	uint8_t _retrans;
-	/**  Use new fallback mechanism (try EDNS, then do TCP) */
-	bool _fallback;
-
-	/**  Whether to do DNSSEC */
-	bool _dnssec;
-	/**  Whether to set the CD bit on DNSSEC requests */
-	bool _dnssec_cd;
-	/** Optional trust anchors for complete DNSSEC validation */
-	ldns_rr_list * _dnssec_anchors;
-	/**  Whether to use tcp or udp (tcp if the value is true)*/
-	bool _usevc;
-	/**  Whether to ignore the tc bit */
-	bool _igntc;
-	/**  Whether to use ip6: 0->does not matter, 1 is IPv4, 2 is IPv6 */
-	uint8_t _ip6;
-	/**  If true append the default domain */
-	bool _defnames;
-	/**  If true apply the search list */
-	bool _dnsrch;
-	/**  Timeout for socket connections */
-	struct timeval _timeout;
-	/**  Only try the first nameserver, and return with an error directly if it fails */
-	bool _fail;
-	/**  Randomly choose a nameserver */
-	bool _random;
-	/** Keep some things to make AXFR possible */
-	int _socket;
-	/** Count the number of LDNS_RR_TYPE_SOA RRs we have seen so far
-	 * (the second one signifies the end of the AXFR)
-	 */
-	int _axfr_soa_count;
-	/* when axfring we get complete packets from the server
-	   but we want to give the caller 1 rr at a time, so
-	   keep the current pkt */
-        /** Packet currently handled when doing part of an AXFR */
-	ldns_pkt *_cur_axfr_pkt;
-	/** Counter for within the AXFR packets */
-	uint16_t _axfr_i;
-	/* EDNS0 available buffer size */
-	uint16_t _edns_udp_size;
-	/* serial for IXFR */
-	uint32_t _serial;
-
-	/* Optional tsig key for signing queries,
-	outgoing messages are signed if and only if both are set
-	*/
-	/** Name of the key to use with TSIG, if _tsig_keyname and _tsig_keydata both contain values, outgoing messages are automatically signed with TSIG. */
-	char *_tsig_keyname;
-	/** Secret key data to use with TSIG, if _tsig_keyname and _tsig_keydata both contain values, outgoing messages are automatically signed with TSIG. */
-	char *_tsig_keydata;
-	/** TSIG signing algorithm */
-	char *_tsig_algorithm;
-
-	/** Source address to query from */
-	ldns_rdf *_source;
-};
-typedef struct ldns_struct_resolver ldns_resolver;
-
-/* prototypes */
-/* read access functions */
-
-/**
- * Get the port the resolver should use
- * \param[in] r the resolver
- * \return the port number
- */
-uint16_t ldns_resolver_port(const ldns_resolver *r);
-
-/**
- * Get the source address the resolver should use
- * \param[in] r the resolver
- * \return the source rdf
- */
-ldns_rdf *ldns_resolver_source(const ldns_resolver *r);
-
-/**
- * Is the resolver set to recurse
- * \param[in] r the resolver
- * \return true if so, otherwise false
- */
-bool ldns_resolver_recursive(const ldns_resolver *r);
-
-/**
- * Get the debug status of the resolver
- * \param[in] r the resolver
- * \return true if so, otherwise false
- */
-bool ldns_resolver_debug(const ldns_resolver *r);
-
-/**
- * Get the number of retries
- * \param[in] r the resolver
- * \return the number of retries
- */
-uint8_t ldns_resolver_retry(const ldns_resolver *r);
-
-/**
- * Get the retransmit interval
- * \param[in] r the resolver
- * \return the retransmit interval
- */
-uint8_t ldns_resolver_retrans(const ldns_resolver *r);
-
-/**
- * Get the truncation fallback status
- * \param[in] r the resolver
- * \return whether the truncation fallback mechanism is used
- */
-bool ldns_resolver_fallback(const ldns_resolver *r);
-
-/**
- * Does the resolver use ip6 or ip4
- * \param[in] r the resolver
- * \return 0: both, 1: ip4, 2:ip6
- */
-uint8_t ldns_resolver_ip6(const ldns_resolver *r);
-
-/**
- * Get the resolver's udp size
- * \param[in] r the resolver
- * \return the udp mesg size
- */
-uint16_t ldns_resolver_edns_udp_size(const ldns_resolver *r);
-/**
- * Does the resolver use tcp or udp
- * \param[in] r the resolver
- * \return true: tcp, false: udp
- */
-bool ldns_resolver_usevc(const ldns_resolver *r);
-/**
- * Does the resolver only try the first nameserver
- * \param[in] r the resolver
- * \return true: yes, fail, false: no, try the others
- */
-bool ldns_resolver_fail(const ldns_resolver *r);
-/**
- * Does the resolver apply default domain name
- * \param[in] r the resolver
- * \return true: yes, false: no
- */
-bool ldns_resolver_defnames(const ldns_resolver *r);
-/**
- * Does the resolver apply search list
- * \param[in] r the resolver
- * \return true: yes, false: no
- */
-bool ldns_resolver_dnsrch(const ldns_resolver *r);
-/**
- * Does the resolver do DNSSEC
- * \param[in] r the resolver
- * \return true: yes, false: no
- */
-bool ldns_resolver_dnssec(const ldns_resolver *r);
-/**
- * Does the resolver set the CD bit
- * \param[in] r the resolver
- * \return true: yes, false: no
- */
-bool ldns_resolver_dnssec_cd(const ldns_resolver *r);
-/**
- * Get the resolver's DNSSEC anchors
- * \param[in] r the resolver
- * \return an rr_list containg trusted DNSSEC anchors
- */
-ldns_rr_list * ldns_resolver_dnssec_anchors(const ldns_resolver *r);
-/**
- * Does the resolver ignore the TC bit (truncated)
- * \param[in] r the resolver
- * \return true: yes, false: no
- */
-bool ldns_resolver_igntc(const ldns_resolver *r);
-/**
- * Does the resolver randomize the nameserver before usage
- * \param[in] r the resolver
- * \return true: yes, false: no
- */
-bool ldns_resolver_random(const ldns_resolver *r);
-/**
- * How many nameserver are configured in the resolver
- * \param[in] r the resolver
- * \return number of nameservers
- */
-size_t ldns_resolver_nameserver_count(const ldns_resolver *r);
-/**
- * What is the default dname to add to relative queries
- * \param[in] r the resolver
- * \return the dname which is added
- */
-ldns_rdf *ldns_resolver_domain(const ldns_resolver *r);
-/**
- * What is the timeout on socket connections
- * \param[in] r the resolver
- * \return the timeout as struct timeval
- */
-struct timeval ldns_resolver_timeout(const ldns_resolver *r);
-/**
- * What is the searchlist as used by the resolver
- * \param[in] r the resolver
- * \return a ldns_rdf pointer to a list of the addresses
- */
-ldns_rdf** ldns_resolver_searchlist(const ldns_resolver *r);
-/**
- * Return the configured nameserver ip address
- * \param[in] r the resolver
- * \return a ldns_rdf pointer to a list of the addresses
- */
-ldns_rdf** ldns_resolver_nameservers(const ldns_resolver *r);
-/**
- * Return the used round trip times for the nameservers
- * \param[in] r the resolver
- * \return a size_t* pointer to the list.
- * yet)
- */
-size_t * ldns_resolver_rtt(const ldns_resolver *r);
-/**
- * Return the used round trip time for a specific nameserver
- * \param[in] r the resolver
- * \param[in] pos the index to the nameserver
- * \return the rrt, 0: infinite, >0: undefined (as of * yet)
- */
-size_t ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos);
-/**
- * Return the tsig keyname as used by the nameserver
- * \param[in] r the resolver
- * \return the name used.
- */
-char *ldns_resolver_tsig_keyname(const ldns_resolver *r);
-/**
- * Return the tsig algorithm as used by the nameserver
- * \param[in] r the resolver
- * \return the algorithm used.
- */
-char *ldns_resolver_tsig_algorithm(const ldns_resolver *r);
-/**
- * Return the tsig keydata as used by the nameserver
- * \param[in] r the resolver
- * \return the keydata used.
- */
-char *ldns_resolver_tsig_keydata(const ldns_resolver *r);
-/**
- * pop the last nameserver from the resolver.
- * \param[in] r the resolver
- * \return the popped address or NULL if empty
- */
-ldns_rdf* ldns_resolver_pop_nameserver(ldns_resolver *r);
-
-/**
- * Return the resolver's searchlist count
- * \param[in] r the resolver
- * \return the searchlist count
- */
-size_t ldns_resolver_searchlist_count(const ldns_resolver *r);
-
-/* write access function */
-/**
- * Set the port the resolver should use
- * \param[in] r the resolver
- * \param[in] p the port number
- */
-void ldns_resolver_set_port(ldns_resolver *r, uint16_t p);
-
-/**
- * Set the source rdf (address) the resolver should use
- * \param[in] r the resolver
- * \param[in] s the source address
- */
-void ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s);
-
-/**
- * Set the resolver recursion
- * \param[in] r the resolver
- * \param[in] b true: set to recurse, false: unset
- */
-void ldns_resolver_set_recursive(ldns_resolver *r, bool b);
-
-/**
- * Set the resolver debugging
- * \param[in] r the resolver
- * \param[in] b true: debug on: false debug off
- */
-void ldns_resolver_set_debug(ldns_resolver *r, bool b);
-
-/**
- * Incremental the resolver's nameserver count.
- * \param[in] r the resolver
- */
-void ldns_resolver_incr_nameserver_count(ldns_resolver *r);
-
-/**
- * Decrement the resolver's nameserver count.
- * \param[in] r the resolver
- */
-void ldns_resolver_dec_nameserver_count(ldns_resolver *r);
-
-/**
- * Set the resolver's nameserver count directly.
- * \param[in] r the resolver
- * \param[in] c the nameserver count
- */
-void ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c);
-
-/**
- * Set the resolver's nameserver count directly by using an rdf list
- * \param[in] r the resolver
- * \param[in] rd the resolver addresses
- */
-void ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **rd);
-
-/**
- * Set the resolver's default domain. This gets appended when no
- * absolute name is given
- * \param[in] r the resolver
- * \param[in] rd the name to append
- */
-void ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *rd);
-
-/**
- * Set the resolver's socket time out when talking to remote hosts
- * \param[in] r the resolver
- * \param[in] timeout the timeout to use
- */
-void ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout);
-
-/**
- * Push a new rd to the resolver's searchlist
- * \param[in] r the resolver
- * \param[in] rd to push
- */
-void ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *rd);
-
-/**
- * Whether the resolver uses the name set with _set_domain
- * \param[in] r the resolver
- * \param[in] b true: use the defaults, false: don't use them
- */
-void ldns_resolver_set_defnames(ldns_resolver *r, bool b);
-
-/**
- * Whether the resolver uses a virtual circuit (TCP)
- * \param[in] r the resolver
- * \param[in] b true: use TCP, false: don't use TCP
- */
-void ldns_resolver_set_usevc(ldns_resolver *r, bool b);
-
-/**
- * Whether the resolver uses the searchlist
- * \param[in] r the resolver
- * \param[in] b true: use the list, false: don't use the list
- */
-void ldns_resolver_set_dnsrch(ldns_resolver *r, bool b);
-
-/**
- * Whether the resolver uses DNSSEC
- * \param[in] r the resolver
- * \param[in] b true: use DNSSEC, false: don't use DNSSEC
- */
-void ldns_resolver_set_dnssec(ldns_resolver *r, bool b);
-
-/**
- * Whether the resolver uses the checking disable bit
- * \param[in] r the resolver
- * \param[in] b true: enable , false: don't use TCP
- */
-void ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool b);
-/**
- * Set the resolver's DNSSEC anchor list directly. RRs should be of type DS or DNSKEY.
- * \param[in] r the resolver
- * \param[in] l the list of RRs to use as trust anchors
- */
-void ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l);
-
-/**
- * Push a new trust anchor to the resolver. It must be a DS or DNSKEY rr
- * \param[in] r the resolver.
- * \param[in] rr the RR to add as a trust anchor.
- * \return a status
- */
-ldns_status ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr);
-
-/**
- * Set the resolver retrans timeout (in seconds)
- * \param[in] r the resolver
- * \param[in] re the retransmission interval in seconds
- */
-void ldns_resolver_set_retrans(ldns_resolver *r, uint8_t re);
-
-/**
- * Set whether the resolvers truncation fallback mechanism is used
- * when ldns_resolver_query() is called.
- * \param[in] r the resolver
- * \param[in] fallback whether to use the fallback mechanism
- */
-void ldns_resolver_set_fallback(ldns_resolver *r, bool fallback);
-
-/**
- * Set the number of times a resolver should retry a nameserver before the
- * next one is tried.
- * \param[in] r the resolver
- * \param[in] re the number of retries
- */
-void ldns_resolver_set_retry(ldns_resolver *r, uint8_t re);
-
-/**
- * Whether the resolver uses ip6
- * \param[in] r the resolver
- * \param[in] i 0: no pref, 1: ip4, 2: ip6
- */
-void ldns_resolver_set_ip6(ldns_resolver *r, uint8_t i);
-
-/**
- * Whether or not to fail after one failed query
- * \param[in] r the resolver
- * \param[in] b true: yes fail, false: continue with next nameserver
- */
-void ldns_resolver_set_fail(ldns_resolver *r, bool b);
-
-/**
- * Whether or not to ignore the TC bit
- * \param[in] r the resolver
- * \param[in] b true: yes ignore, false: don't ignore
- */
-void ldns_resolver_set_igntc(ldns_resolver *r, bool b);
-
-/**
- * Set maximum udp size
- * \param[in] r the resolver
- * \param[in] s the udp max size
- */
-void ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s);
-
-/**
- * Set the tsig key name
- * \param[in] r the resolver
- * \param[in] tsig_keyname the tsig key name
- */
-void ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname);
-
-/**
- * Set the tsig algorithm
- * \param[in] r the resolver
- * \param[in] tsig_algorithm the tsig algorithm
- */
-void ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm);
-
-/**
- * Set the tsig key data
- * \param[in] r the resolver
- * \param[in] tsig_keydata the key data
- */
-void ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata);
-
-/**
- * Set round trip time for all nameservers. Note this currently
- * differentiates between: unreachable and reachable.
- * \param[in] r the resolver
- * \param[in] rtt a list with the times
- */
-void ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt);
-
-/**
- * Set round trip time for a specific nameserver. Note this
- * currently differentiates between: unreachable and reachable.
- * \param[in] r the resolver
- * \param[in] pos the nameserver position
- * \param[in] value the rtt
- */
-void ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value);
-
-/**
- * Should the nameserver list be randomized before each use
- * \param[in] r the resolver
- * \param[in] b: true: randomize, false: don't
- */
-void ldns_resolver_set_random(ldns_resolver *r, bool b);
-
-/**
- * Push a new nameserver to the resolver. It must be an IP
- * address v4 or v6.
- * \param[in] r the resolver
- * \param[in] n the ip address
- * \return ldns_status a status
- */
-ldns_status ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n);
-
-/**
- * Push a new nameserver to the resolver. It must be an
- * A or AAAA RR record type
- * \param[in] r the resolver
- * \param[in] rr the resource record
- * \return ldns_status a status
- */
-ldns_status ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr);
-
-/**
- * Push a new nameserver rr_list to the resolver.
- * \param[in] r the resolver
- * \param[in] rrlist the rr_list to push
- * \return ldns_status a status
- */
-ldns_status ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list *rrlist);
-
-/**
- * Send the query for using the resolver and take the search list into account
- * The search algorithm is as follows:
- * If the name is absolute, try it as-is, otherwise apply the search list
- * \param[in] *r operate using this resolver
- * \param[in] *rdf query for this name
- * \param[in] t query for this type (may be 0, defaults to A)
- * \param[in] c query for this class (may be 0, default to IN)
- * \param[in] flags the query flags
- *
- * \return ldns_pkt* a packet with the reply from the nameserver
- */
-ldns_pkt* ldns_resolver_search(const ldns_resolver *r, const ldns_rdf *rdf, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
-
-
-/**
- * Send the query for using the resolver and take the search list into account
- * The search algorithm is as follows:
- * If the name is absolute, try it as-is, otherwise apply the search list
- * \param[out] pkt a packet with the reply from the nameserver
- * \param[in] *r operate using this resolver
- * \param[in] *rdf query for this name
- * \param[in] t query for this type (may be 0, defaults to A)
- * \param[in] c query for this class (may be 0, default to IN)
- * \param[in] flags the query flags
- *
- * \return ldns_status LDNS_STATUS_OK on success
- */
-ldns_status ldns_resolver_search_status(ldns_pkt** pkt, ldns_resolver *r, const ldns_rdf *rdf, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
-
-/**
- * Form a query packet from a resolver and name/type/class combo
- * \param[out] **q a pointer to a ldns_pkt pointer (initialized by this function)
- * \param[in] *r operate using this resolver
- * \param[in] *name query for this name
- * \param[in] t query for this type (may be 0, defaults to A)
- * \param[in] c query for this class (may be 0, default to IN)
- * \param[in] f the query flags
- *
- * \return ldns_pkt* a packet with the reply from the nameserver
- */
-ldns_status ldns_resolver_prepare_query_pkt(ldns_pkt **q, ldns_resolver *r, const  ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t f);
-
-/**
- * Send the query for name as-is
- * \param[out] **answer a pointer to a ldns_pkt pointer (initialized by this function)
- * \param[in] *r operate using this resolver
- * \param[in] *name query for this name
- * \param[in] t query for this type (may be 0, defaults to A)
- * \param[in] c query for this class (may be 0, default to IN)
- * \param[in] flags the query flags
- *
- * \return ldns_pkt* a packet with the reply from the nameserver
- */
-ldns_status ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
-
-/**
- * Send the given packet to a nameserver
- * \param[out] **answer a pointer to a ldns_pkt pointer (initialized by this function)
- * \param[in] *r operate using this resolver
- * \param[in] *query_pkt query
- */
-ldns_status ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, ldns_pkt *query_pkt);
-
-/**
- * Send a query to a nameserver
- * \param[out] pkt a packet with the reply from the nameserver
- * \param[in] *r operate using this resolver
- * \param[in] *name query for this name
- * \param[in] *t query for this type (may be 0, defaults to A)
- * \param[in] *c query for this class (may be 0, default to IN)
- * \param[in] flags the query flags
- *
- * \return ldns_status LDNS_STATUS_OK on success
- * if _defnames is true the default domain will be added
- */
-ldns_status ldns_resolver_query_status(ldns_pkt** pkt, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
-
-
-/**
- * Send a query to a nameserver
- * \param[in] *r operate using this resolver 
- *               (despite the const in the declaration,
- *                the struct is altered as a side-effect)
- * \param[in] *name query for this name
- * \param[in] *t query for this type (may be 0, defaults to A)
- * \param[in] *c query for this class (may be 0, default to IN)
- * \param[in] flags the query flags
- *
- * \return ldns_pkt* a packet with the reply from the nameserver
- * if _defnames is true the default domain will be added
- */
-ldns_pkt* ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
-
-
-/**
- * Create a new resolver structure
- * \return ldns_resolver* pointer to new structure
- */
-ldns_resolver* ldns_resolver_new(void);
-
-/**
- * Clone a resolver
- * \param[in] r the resolver to clone
- * \return ldns_resolver* pointer to new structure
- */
-ldns_resolver* ldns_resolver_clone(ldns_resolver *r);
-
-/**
- * Create a resolver structure from a file like /etc/resolv.conf
- * \param[out] r the new resolver
- * \param[in] fp file pointer to create new resolver from
- *      if NULL use /etc/resolv.conf
- * \return LDNS_STATUS_OK or the error
- */
-ldns_status ldns_resolver_new_frm_fp(ldns_resolver **r, FILE *fp);
-
-/**
- * Create a resolver structure from a file like /etc/resolv.conf
- * \param[out] r the new resolver
- * \param[in] fp file pointer to create new resolver from
- *      if NULL use /etc/resolv.conf
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \return LDNS_STATUS_OK or the error
- */
-ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **r, FILE *fp, int *line_nr);
-
-/**
- * Configure a resolver by means of a resolv.conf file
- * The file may be NULL in which case there will  be
- * looked the RESOLV_CONF (defaults to /etc/resolv.conf
- * \param[out] r the new resolver
- * \param[in] filename the filename to use
- * \return LDNS_STATUS_OK or the error
- */
-ldns_status ldns_resolver_new_frm_file(ldns_resolver **r, const char *filename);
-
-/**
- * Frees the allocated space for this resolver. Only frees the resolver pionter! You should probably be using _deep_free.
- * \param res resolver to free
- */
-void ldns_resolver_free(ldns_resolver *res);
-
-/**
- * Frees the allocated space for this resolver and all it's data
- * \param res resolver to free
- */
-void ldns_resolver_deep_free(ldns_resolver *res);
-
-/**
- * Get the next stream of RRs in a AXFR
- * \param[in] resolver the resolver to use. First ldns_axfr_start() must be
- * called
- * \return ldns_rr the next RR from the AXFR stream
- * After you get this returned RR (not NULL: on error), then check if 
- * ldns_axfr_complete() is true to see if the zone transfer has completed.
- */
-ldns_rr* ldns_axfr_next(ldns_resolver *resolver);
-
-/**
- * Abort a transfer that is in progress
- * \param[in] resolver the resolver that is used
- */
-void ldns_axfr_abort(ldns_resolver *resolver);
-
-/**
- * Returns true if the axfr transfer has completed (i.e. 2 SOA RRs and no errors were encountered
- * \param[in] resolver the resolver that is used
- * \return bool true if axfr transfer was completed without error
- */
-bool ldns_axfr_complete(const ldns_resolver *resolver);
-
-/**
- * Returns a pointer to the last ldns_pkt that was sent by the server in the AXFR transfer
- * uasable for instance to get the error code on failure
- * \param[in] res the resolver that was used in the axfr transfer
- * \return ldns_pkt the last packet sent
- */
-ldns_pkt *ldns_axfr_last_pkt(const ldns_resolver *res);
-
-/**
- * Get the serial for requesting IXFR.
- * \param[in] r the resolver
- * \param[in] serial serial
- */
-void ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial);
-
-/**
- * Get the serial for requesting IXFR.
- * \param[in] res the resolver
- * \return uint32_t serial
- */
-uint32_t ldns_resolver_get_ixfr_serial(const ldns_resolver *res);
-
-/**
- * Randomize the nameserver list in the resolver
- * \param[in] r the resolver
- */
-void ldns_resolver_nameservers_randomize(ldns_resolver *r);
-
-/**
- * Returns true if at least one of the provided keys is a trust anchor
- * \param[in] r the current resolver
- * \param[in] keys the keyset to check
- * \param[out] trusted_keys the subset of trusted keys in the 'keys' rrset
- * \return true if at least one of the provided keys is a configured trust anchor
- */
-bool ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* LDNS_RESOLVER_H */
diff --git a/include/ldns/rr.h b/include/ldns/rr.h
deleted file mode 100644
index 75ac352..0000000
--- a/include/ldns/rr.h
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- * rr.h -  resource record definitions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file
- *
- * Contains the definition of ldns_rr and functions to manipulate those.
- */
-
-
-#ifndef LDNS_RR_H
-#define LDNS_RR_H
-
-#include <ldns/common.h>
-#include <ldns/rdata.h>
-#include <ldns/buffer.h>
-#include <ldns/error.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Maximum length of a dname label */
-#define LDNS_MAX_LABELLEN     63
-/** Maximum length of a complete dname */
-#define LDNS_MAX_DOMAINLEN    255
-/** Maximum number of pointers in 1 dname */
-#define LDNS_MAX_POINTERS	65535
-/** The bytes TTL, CLASS and length use up in an rr */
-#define LDNS_RR_OVERHEAD	10
-
-/* The first fields are contiguous and can be referenced instantly */
-#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 258
-
-
-
-/**
- *  The different RR classes.
- */
-enum ldns_enum_rr_class
-{
-	/** the Internet */
-	LDNS_RR_CLASS_IN 	= 1,
-	/** Chaos class */
-	LDNS_RR_CLASS_CH	= 3,
-	/** Hesiod (Dyer 87) */
-	LDNS_RR_CLASS_HS	= 4,
-    /** None class, dynamic update */
-    LDNS_RR_CLASS_NONE      = 254,
-	/** Any class */
-	LDNS_RR_CLASS_ANY	= 255,
-
-	LDNS_RR_CLASS_FIRST     = 0,
-	LDNS_RR_CLASS_LAST      = 65535,
-	LDNS_RR_CLASS_COUNT     = LDNS_RR_CLASS_LAST - LDNS_RR_CLASS_FIRST + 1
-};
-typedef enum ldns_enum_rr_class ldns_rr_class;
-
-/**
- *  Used to specify whether compression is allowed.
- */
-enum ldns_enum_rr_compress
-{
-	/** compression is allowed */
-	LDNS_RR_COMPRESS,
-	LDNS_RR_NO_COMPRESS
-};
-typedef enum ldns_enum_rr_compress ldns_rr_compress;
-
-/**
- * The different RR types.
- */
-enum ldns_enum_rr_type
-{
-	/**  a host address */
-	LDNS_RR_TYPE_A = 1,
-	/**  an authoritative name server */
-	LDNS_RR_TYPE_NS = 2,
-	/**  a mail destination (Obsolete - use MX) */
-	LDNS_RR_TYPE_MD = 3,
-	/**  a mail forwarder (Obsolete - use MX) */
-	LDNS_RR_TYPE_MF = 4,
-	/**  the canonical name for an alias */
-	LDNS_RR_TYPE_CNAME = 5,
-	/**  marks the start of a zone of authority */
-	LDNS_RR_TYPE_SOA = 6,
-	/**  a mailbox domain name (EXPERIMENTAL) */
-	LDNS_RR_TYPE_MB = 7,
-	/**  a mail group member (EXPERIMENTAL) */
-	LDNS_RR_TYPE_MG = 8,
-	/**  a mail rename domain name (EXPERIMENTAL) */
-	LDNS_RR_TYPE_MR = 9,
-	/**  a null RR (EXPERIMENTAL) */
-	LDNS_RR_TYPE_NULL = 10,
-	/**  a well known service description */
-	LDNS_RR_TYPE_WKS = 11,
-	/**  a domain name pointer */
-	LDNS_RR_TYPE_PTR = 12,
-	/**  host information */
-	LDNS_RR_TYPE_HINFO = 13,
-	/**  mailbox or mail list information */
-	LDNS_RR_TYPE_MINFO = 14,
-	/**  mail exchange */
-	LDNS_RR_TYPE_MX = 15,
-	/**  text strings */
-	LDNS_RR_TYPE_TXT = 16,
-	/**  RFC1183 */
-	LDNS_RR_TYPE_RP = 17,
-	/**  RFC1183 */
-	LDNS_RR_TYPE_AFSDB = 18,
-	/**  RFC1183 */
-	LDNS_RR_TYPE_X25 = 19,
-	/**  RFC1183 */
-	LDNS_RR_TYPE_ISDN = 20,
-	/**  RFC1183 */
-	LDNS_RR_TYPE_RT = 21,
-	/**  RFC1706 */
-	LDNS_RR_TYPE_NSAP = 22,
-	/**  RFC1348 */
-	LDNS_RR_TYPE_NSAP_PTR = 23,
-	/**  2535typecode */
-	LDNS_RR_TYPE_SIG = 24,
-	/**  2535typecode */
-	LDNS_RR_TYPE_KEY = 25,
-	/**  RFC2163 */
-	LDNS_RR_TYPE_PX = 26,
-	/**  RFC1712 */
-	LDNS_RR_TYPE_GPOS = 27,
-	/**  ipv6 address */
-	LDNS_RR_TYPE_AAAA = 28,
-	/**  LOC record  RFC1876 */
-	LDNS_RR_TYPE_LOC = 29,
-	/**  2535typecode */
-	LDNS_RR_TYPE_NXT = 30,
-	/**  draft-ietf-nimrod-dns-01.txt */
-	LDNS_RR_TYPE_EID = 31,
-	/**  draft-ietf-nimrod-dns-01.txt */
-	LDNS_RR_TYPE_NIMLOC = 32,
-	/**  SRV record RFC2782 */
-	LDNS_RR_TYPE_SRV = 33,
-	/**  http://www.jhsoft.com/rfc/af-saa-0069.000.rtf */
-	LDNS_RR_TYPE_ATMA = 34,
-	/**  RFC2915 */
-	LDNS_RR_TYPE_NAPTR = 35,
-	/**  RFC2230 */
-	LDNS_RR_TYPE_KX = 36,
-	/**  RFC2538 */
-	LDNS_RR_TYPE_CERT = 37,
-	/**  RFC2874 */
-	LDNS_RR_TYPE_A6 = 38,
-	/**  RFC2672 */
-	LDNS_RR_TYPE_DNAME = 39,
-	/**  dnsind-kitchen-sink-02.txt */
-	LDNS_RR_TYPE_SINK = 40,
-	/**  Pseudo OPT record... */
-	LDNS_RR_TYPE_OPT = 41,
-	/**  RFC3123 */
-	LDNS_RR_TYPE_APL = 42,
-	/**  RFC4034, RFC3658 */
-	LDNS_RR_TYPE_DS = 43,
-	/**  SSH Key Fingerprint */
-	LDNS_RR_TYPE_SSHFP = 44, /* RFC 4255 */
-	/**  IPsec Key */
-	LDNS_RR_TYPE_IPSECKEY = 45, /* RFC 4025 */
-	/**  DNSSEC */
-	LDNS_RR_TYPE_RRSIG = 46, /* RFC 4034 */
-	LDNS_RR_TYPE_NSEC = 47, /* RFC 4034 */
-	LDNS_RR_TYPE_DNSKEY = 48, /* RFC 4034 */
-
-	LDNS_RR_TYPE_DHCID = 49, /* RFC 4701 */
-	/* NSEC3 */
-	LDNS_RR_TYPE_NSEC3 = 50, /* RFC 5155 */
-	LDNS_RR_TYPE_NSEC3PARAM = 51, /* RFC 5155 */
-	LDNS_RR_TYPE_NSEC3PARAMS = 51,
-	LDNS_RR_TYPE_TLSA = 52, /* RFC 6698 */
-
-	LDNS_RR_TYPE_HIP = 55, /* RFC 5205 */
-
-	/** draft-reid-dnsext-zs */
-	LDNS_RR_TYPE_NINFO = 56,
-	/** draft-reid-dnsext-rkey */
-	LDNS_RR_TYPE_RKEY = 57,
-        /** draft-ietf-dnsop-trust-history */
-        LDNS_RR_TYPE_TALINK = 58,
-	LDNS_RR_TYPE_CDS = 59, /* RFC 7344 */
-	LDNS_RR_TYPE_CDNSKEY = 60, /* RFC 7344 */
-	/** draft-ietf-dane-openpgpkey */
-	LDNS_RR_TYPE_OPENPGPKEY = 61,
-
-	LDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
-
-	LDNS_RR_TYPE_UINFO = 100,
-	LDNS_RR_TYPE_UID = 101,
-	LDNS_RR_TYPE_GID = 102,
-	LDNS_RR_TYPE_UNSPEC = 103,
-
-	LDNS_RR_TYPE_NID = 104, /* RFC 6742 */
-	LDNS_RR_TYPE_L32 = 105, /* RFC 6742 */
-	LDNS_RR_TYPE_L64 = 106, /* RFC 6742 */
-	LDNS_RR_TYPE_LP = 107, /* RFC 6742 */
-
-	LDNS_RR_TYPE_EUI48 = 108, /* RFC 7043 */
-	LDNS_RR_TYPE_EUI64 = 109, /* RFC 7043 */
-
-	LDNS_RR_TYPE_TKEY = 249, /* RFC 2930 */
-	LDNS_RR_TYPE_TSIG = 250,
-	LDNS_RR_TYPE_IXFR = 251,
-	LDNS_RR_TYPE_AXFR = 252,
-	/**  A request for mailbox-related records (MB, MG or MR) */
-	LDNS_RR_TYPE_MAILB = 253,
-	/**  A request for mail agent RRs (Obsolete - see MX) */
-	LDNS_RR_TYPE_MAILA = 254,
-	/**  any type (wildcard) */
-	LDNS_RR_TYPE_ANY = 255,
-	/** draft-faltstrom-uri-06 */
-	LDNS_RR_TYPE_URI = 256,
-	LDNS_RR_TYPE_CAA = 257, /* RFC 6844 */
-
-	/** DNSSEC Trust Authorities */
-	LDNS_RR_TYPE_TA = 32768,
-	/* RFC 4431, 5074, DNSSEC Lookaside Validation */
-	LDNS_RR_TYPE_DLV = 32769,
-
-	/* type codes from nsec3 experimental phase
-	LDNS_RR_TYPE_NSEC3 = 65324,
-	LDNS_RR_TYPE_NSEC3PARAMS = 65325, */
-	LDNS_RR_TYPE_FIRST = 0,
-	LDNS_RR_TYPE_LAST  = 65535,
-	LDNS_RR_TYPE_COUNT = LDNS_RR_TYPE_LAST - LDNS_RR_TYPE_FIRST + 1
-};
-typedef enum ldns_enum_rr_type ldns_rr_type;
-
-/**
- * Resource Record
- *
- * This is the basic DNS element that contains actual data
- *
- * From RFC1035:
- * <pre>
-3.2.1. Format
-
-All RRs have the same top level format shown below:
-
-                                    1  1  1  1  1  1
-      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                                               |
-    /                                               /
-    /                      NAME                     /
-    |                                               |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                      TYPE                     |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                     CLASS                     |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                      TTL                      |
-    |                                               |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-    |                   RDLENGTH                    |
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
-    /                     RDATA                     /
-    /                                               /
-    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-
-where:
-
-NAME            an owner name, i.e., the name of the node to which this
-                resource record pertains.
-
-TYPE            two octets containing one of the RR TYPE codes.
-
-CLASS           two octets containing one of the RR CLASS codes.
-
-TTL             a 32 bit signed integer that specifies the time interval
-                that the resource record may be cached before the source
-                of the information should again be consulted.  Zero
-                values are interpreted to mean that the RR can only be
-                used for the transaction in progress, and should not be
-                cached.  For example, SOA records are always distributed
-                with a zero TTL to prohibit caching.  Zero values can
-                also be used for extremely volatile data.
-
-RDLENGTH        an unsigned 16 bit integer that specifies the length in
-                octets of the RDATA field.
-
-RDATA           a variable length string of octets that describes the
-                resource.  The format of this information varies
-                according to the TYPE and CLASS of the resource record.
- * </pre>
- *
- * The actual amount and type of rdata fields depend on the RR type of the
- * RR, and can be found by using \ref ldns_rr_descriptor functions.
- */
-struct ldns_struct_rr
-{
-	/**  Owner name, uncompressed */
-	ldns_rdf	*_owner;
-	/**  Time to live  */
-	uint32_t	_ttl;
-	/**  Number of data fields */
-	size_t	        _rd_count;
-	/**  the type of the RR. A, MX etc. */
-	ldns_rr_type	_rr_type;
-	/**  Class of the resource record.  */
-	ldns_rr_class	_rr_class;
-	/* everything in the rdata is in network order */
-	/**  The array of rdata's */
-	ldns_rdf	 **_rdata_fields;
-	/**  question rr [it would be nicer if thous is after _rd_count]
-		 ABI change: Fix this in next major release
-	 */
-	bool		_rr_question;
-};
-typedef struct ldns_struct_rr ldns_rr;
-
-/**
- * List or Set of Resource Records
- *
- * Contains a list of rr's <br>
- * No official RFC-like checks are made
- */
-struct ldns_struct_rr_list
-{
-	size_t _rr_count;
-	size_t _rr_capacity;
-	ldns_rr **_rrs;
-};
-typedef struct ldns_struct_rr_list ldns_rr_list;
-
-/**
- * Contains all information about resource record types.
- *
- * This structure contains, for all rr types, the rdata fields that are defined.
- */
-struct ldns_struct_rr_descriptor
-{
-	/** Type of the RR that is described here */
-	ldns_rr_type    _type;
-	/** Textual name of the RR type.  */
-	const char *_name;
-	/** Minimum number of rdata fields in the RRs of this type.  */
-	uint8_t     _minimum;
-	/** Maximum number of rdata fields in the RRs of this type.  */
-	uint8_t     _maximum;
-	/** Wireformat specification for the rr, i.e. the types of rdata fields in their respective order. */
-	const ldns_rdf_type *_wireformat;
-	/** Special rdf types */
-	ldns_rdf_type _variable;
-	/** Specifies whether compression can be used for dnames in this RR type. */
-	ldns_rr_compress _compress;
-	/** The number of DNAMEs in the _wireformat string, for parsing. */
-	uint8_t _dname_count;
-};
-typedef struct ldns_struct_rr_descriptor ldns_rr_descriptor;
-
-
-/**
- * Create a rr type bitmap rdf providing enough space to set all 
- * known (to ldns) rr types.
- * \param[out] rdf the constructed rdf
- * \return LDNS_STATUS_OK if all went well.
- */
-ldns_status ldns_rdf_bitmap_known_rr_types_space(ldns_rdf** rdf);
-
-/**
- * Create a rr type bitmap rdf with at least all known (to ldns) rr types set.
- * \param[out] rdf the constructed rdf
- * \return LDNS_STATUS_OK if all went well.
- */
-ldns_status ldns_rdf_bitmap_known_rr_types(ldns_rdf** rdf);
-
-
-/**
- * creates a new rr structure.
- * \return ldns_rr *
- */
-ldns_rr* ldns_rr_new(void);
-
-/**
- * creates a new rr structure, based on the given type.
- * alloc enough space to hold all the rdf's
- */
-ldns_rr* ldns_rr_new_frm_type(ldns_rr_type t);
-
-/**
- * frees an RR structure
- * \param[in] *rr the RR to be freed
- * \return void
- */
-void ldns_rr_free(ldns_rr *rr);
-
-/**
- * creates an rr from a string.
- * The string should be a fully filled-in rr, like
- * ownername &lt;space&gt; TTL &lt;space&gt; CLASS &lt;space&gt;
- * TYPE &lt;space&gt; RDATA.
- * \param[out] n the rr to return
- * \param[in] str the string to convert
- * \param[in] default_ttl default ttl value for the rr.
- *            If 0 DEF_TTL will be used
- * \param[in] origin when the owner is relative add this.
- *	The caller must ldns_rdf_deep_free it.
- * \param[out] prev the previous ownername. if this value is not NULL,
- * the function overwrites this with the ownername found in this
- * string. The caller must then ldns_rdf_deep_free it.
- * \return a status msg describing an error or LDNS_STATUS_OK
- */
-ldns_status ldns_rr_new_frm_str(ldns_rr **n, const char *str,
-                                uint32_t default_ttl, ldns_rdf *origin,
-                                ldns_rdf **prev);
-
-/**
- * creates an rr for the question section from a string, i.e.
- * without RDATA fields
- * Origin and previous RR functionality are the same as in
- * ldns_rr_new_frm_str()
- * \param[out] n the rr to return
- * \param[in] str the string to convert
- * \param[in] origin when the owner is relative add this.
- *	The caller must ldns_rdf_deep_free it.
- * \param prev the previous ownername. the function overwrite this with
- * the current found ownername. The caller must ldns_rdf_deep_free it.
- * \return a status msg describing an error or LDNS_STATUS_OK
- */
-ldns_status ldns_rr_new_question_frm_str(ldns_rr **n, const char *str,
-                                ldns_rdf *origin, ldns_rdf **prev);
-
-/**
- * creates a new rr from a file containing a string.
- * \param[out] rr the new rr
- * \param[in] fp the file pointer to use
- * \param[in] default_ttl pointer to a default ttl for the rr. If NULL DEF_TTL will be used
- *            the pointer will be updated if the file contains a $TTL directive
- * \param[in] origin when the owner is relative add this
- * 	      the pointer will be updated if the file contains a $ORIGIN directive
- *	      The caller must ldns_rdf_deep_free it.
- * \param[in] prev when the owner is whitespaces use this as the * ownername
- *            the pointer will be updated after the call
- *	      The caller must ldns_rdf_deep_free it.
- * \return a ldns_status with an error or LDNS_STATUS_OK
- */
-ldns_status ldns_rr_new_frm_fp(ldns_rr **rr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev);
-
-/**
- * creates a new rr from a file containing a string.
- * \param[out] rr the new rr
- * \param[in] fp the file pointer to use
- * \param[in] default_ttl a default ttl for the rr. If NULL DEF_TTL will be used
- *            the pointer will be updated if the file contains a $TTL directive
- * \param[in] origin when the owner is relative add this
- * 	      the pointer will be updated if the file contains a $ORIGIN directive
- *	      The caller must ldns_rdf_deep_free it.
- * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
- * \param[in] prev when the owner is whitespaces use this as the * ownername
- *            the pointer will be updated after the call
- *	      The caller must ldns_rdf_deep_free it.
- * \return a ldns_status with an error or LDNS_STATUS_OK
- */
-ldns_status ldns_rr_new_frm_fp_l(ldns_rr **rr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr);
-
-/**
- * sets the owner in the rr structure.
- * \param[in] *rr rr to operate on
- * \param[in] *owner set to this owner
- * \return void
- */
-void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner);
-
-/**
- * sets the question flag in the rr structure.
- * \param[in] *rr rr to operate on
- * \param[in] question question flag
- * \return void
- */
-void ldns_rr_set_question(ldns_rr *rr, bool question);
-
-/**
- * sets the ttl in the rr structure.
- * \param[in] *rr rr to operate on
- * \param[in] ttl set to this ttl
- * \return void
- */
-void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl);
-
-/**
- * sets the rd_count in the rr.
- * \param[in] *rr rr to operate on
- * \param[in] count set to this count
- * \return void
- */
-void ldns_rr_set_rd_count(ldns_rr *rr, size_t count);
-
-/**
- * sets the type in the rr.
- * \param[in] *rr rr to operate on
- * \param[in] rr_type set to this type
- * \return void
- */
-void ldns_rr_set_type(ldns_rr *rr, ldns_rr_type rr_type);
-
-/**
- * sets the class in the rr.
- * \param[in] *rr rr to operate on
- * \param[in] rr_class set to this class
- * \return void
- */
-void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class);
-
-/**
- * sets a rdf member, it will be set on the
- * position given. The old value is returned, like pop.
- * \param[in] *rr the rr to operate on
- * \param[in] *f the rdf to set
- * \param[in] position the position the set the rdf
- * \return  the old value in the rr, NULL on failyre
- */
-ldns_rdf* ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position);
-
-/**
- * sets rd_field member, it will be
- * placed in the next available spot.
- * \param[in] *rr rr to operate on
- * \param[in] *f the data field member to set
- * \return bool
- */
-bool ldns_rr_push_rdf(ldns_rr *rr, const ldns_rdf *f);
-
-/**
- * removes a rd_field member, it will be
- * popped from the last position.
- * \param[in] *rr rr to operate on
- * \return rdf which was popped (null if nothing)
- */
-ldns_rdf* ldns_rr_pop_rdf(ldns_rr *rr);
-
-/**
- * returns the rdata field member counter.
- * \param[in] *rr rr to operate on
- * \param[in] nr the number of the rdf to return
- * \return ldns_rdf *
- */
-ldns_rdf* ldns_rr_rdf(const ldns_rr *rr, size_t nr);
-
-/**
- * returns the owner name of an rr structure.
- * \param[in] *rr rr to operate on
- * \return ldns_rdf *
- */
-ldns_rdf* ldns_rr_owner(const ldns_rr *rr);
-
-/**
- * returns the question flag of an rr structure.
- * \param[in] *rr rr to operate on
- * \return bool true if question
- */
-bool ldns_rr_is_question(const ldns_rr *rr);
-
-/**
- * returns the ttl of an rr structure.
- * \param[in] *rr the rr to read from
- * \return the ttl of the rr
- */
-uint32_t ldns_rr_ttl(const ldns_rr *rr);
-
-/**
- * returns the rd_count of an rr structure.
- * \param[in] *rr the rr to read from
- * \return the rd count of the rr
- */
-size_t ldns_rr_rd_count(const ldns_rr *rr);
-
-/**
- * returns the type of the rr.
- * \param[in] *rr the rr to read from
- * \return the type of the rr
- */
-ldns_rr_type ldns_rr_get_type(const ldns_rr *rr);
-
-/**
- * returns the class of the rr.
- * \param[in] *rr the rr to read from
- * \return the class of the rr
- */
-ldns_rr_class ldns_rr_get_class(const ldns_rr *rr);
-
-/* rr_lists */
-
-/**
- * returns the number of rr's in an rr_list.
- * \param[in] rr_list  the rr_list to read from
- * \return the number of rr's
- */
-size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list);
-
-/**
- * sets the number of rr's in an rr_list.
- * \param[in] rr_list the rr_list to set the count on
- * \param[in] count the number of rr in this list
- * \return void
- */
-void ldns_rr_list_set_rr_count(ldns_rr_list *rr_list, size_t count);
-
-/**
- * set a rr on a specific index in a ldns_rr_list
- * \param[in] rr_list the rr_list to use
- * \param[in] r the rr to set
- * \param[in] count index into the rr_list
- * \return the old rr which was stored in the rr_list, or
- * NULL is the index was too large
- * set a specific rr */
-ldns_rr * ldns_rr_list_set_rr(ldns_rr_list *rr_list, const ldns_rr *r, size_t count);
-
-/**
- * returns a specific rr of an rrlist.
- * \param[in] rr_list the rr_list to read from
- * \param[in] nr return this rr
- * \return the rr at position nr
- */
-ldns_rr* ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr);
-
-/**
- * creates a new rr_list structure.
- * \return a new rr_list structure
- */
-ldns_rr_list* ldns_rr_list_new(void);
-
-/**
- * frees an rr_list structure.
- * \param[in] rr_list the list to free
- */
-void ldns_rr_list_free(ldns_rr_list *rr_list);
-
-/**
- * frees an rr_list structure and all rrs contained therein.
- * \param[in] rr_list the list to free
- */
-void ldns_rr_list_deep_free(ldns_rr_list *rr_list);
-
-/**
- * concatenates two ldns_rr_lists together. This modifies
- * *left (to extend it and add the pointers from *right).
- * \param[in] left the leftside
- * \param[in] right the rightside
- * \return a left with right concatenated to it
- */
-bool ldns_rr_list_cat(ldns_rr_list *left, ldns_rr_list *right);
-
-/**
- * concatenates two ldns_rr_lists together, but makes clones of the rr's 
- * (instead of pointer copying).
- * \param[in] left the leftside
- * \param[in] right the rightside
- * \return a new rr_list with leftside/rightside concatenated
- */
-ldns_rr_list* ldns_rr_list_cat_clone(ldns_rr_list *left, ldns_rr_list *right);
-
-/**
- * pushes an rr to an rrlist.
- * \param[in] rr_list the rr_list to push to 
- * \param[in] rr the rr to push 
- * \return false on error, otherwise true
- */
-bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr);
-
-/**
- * pushes an rr_list to an rrlist.
- * \param[in] rr_list the rr_list to push to 
- * \param[in] push_list the rr_list to push 
- * \return false on error, otherwise true
- */
-bool ldns_rr_list_push_rr_list(ldns_rr_list *rr_list, const ldns_rr_list *push_list);
-
-/**
- * pops the last rr from an rrlist.
- * \param[in] rr_list the rr_list to pop from
- * \return NULL if nothing to pop. Otherwise the popped RR
- */
-ldns_rr* ldns_rr_list_pop_rr(ldns_rr_list *rr_list);
-
-/**
- * pops an  rr_list of size s from an rrlist.
- * \param[in] rr_list the rr_list to pop from
- * \param[in] size the number of rr's to pop 
- * \return NULL if nothing to pop. Otherwise the popped rr_list
- */
-ldns_rr_list* ldns_rr_list_pop_rr_list(ldns_rr_list *rr_list, size_t size);
-
-/**
- * returns true if the given rr is one of the rrs in the
- * list, or if it is equal to one
- * \param[in] rr_list the rr_list to check
- * \param[in] rr the rr to check
- * \return true if rr_list contains rr, false otherwise
- */
-bool ldns_rr_list_contains_rr(const ldns_rr_list *rr_list, ldns_rr *rr); 
-
-/**
- * checks if an rr_list is a rrset.
- * \param[in] rr_list the rr_list to check
- * \return true if it is an rrset otherwise false
- */
-bool ldns_is_rrset(ldns_rr_list *rr_list);
-
-/**
- * pushes an rr to an rrset (which really are rr_list's).
- * \param[in] *rr_list the rrset to push the rr to
- * \param[in] *rr the rr to push
- * \return true if the push succeeded otherwise false
- */
-bool ldns_rr_set_push_rr(ldns_rr_list *rr_list, ldns_rr *rr);
-
-/**
- * pops the last rr from an rrset. This function is there only
- * for the symmetry.
- * \param[in] rr_list the rr_list to pop from
- * \return NULL if nothing to pop. Otherwise the popped RR
- *
- */
-ldns_rr* ldns_rr_set_pop_rr(ldns_rr_list *rr_list);
-
-/**
- * pops the first rrset from the list,
- * the list must be sorted, so that all rr's from each rrset
- * are next to each other
- */
-ldns_rr_list *ldns_rr_list_pop_rrset(ldns_rr_list *rr_list);
-
-
-/**
- * retrieves a rrtype by looking up its name.
- * \param[in] name a string with the name
- * \return the type which corresponds with the name
- */
-ldns_rr_type ldns_get_rr_type_by_name(const char *name);
-
-/**
- * retrieves a class by looking up its name.
- * \param[in] name string with the name
- * \return the cass which corresponds with the name
- */
-ldns_rr_class ldns_get_rr_class_by_name(const char *name);
-
-/**
- * clones a rr and all its data
- * \param[in] rr the rr to clone
- * \return the new rr or NULL on failure
- */
-ldns_rr* ldns_rr_clone(const ldns_rr *rr);
-
-/**
- * clones an rrlist.
- * \param[in] rrlist the rrlist to clone
- * \return the cloned rr list
- */
-ldns_rr_list* ldns_rr_list_clone(const ldns_rr_list *rrlist);
-
-/**
- * sorts an rr_list (canonical wire format). the sorting is done inband.
- * \param[in] unsorted the rr_list to be sorted
- * \return void
- */
-void ldns_rr_list_sort(ldns_rr_list *unsorted);
-
-/**
- * compares two rrs. The TTL is not looked at.
- * \param[in] rr1 the first one
- * \param[in] rr2 the second one
- * \return 0 if equal
- *         -1 if rr1 comes before rr2
- *         +1 if rr2 comes before rr1
- */
-int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2);
-
-/**
- * compares two rrs, up to the rdata.
- * \param[in] rr1 the first one
- * \param[in] rr2 the second one
- * \return 0 if equal
- *         -1 if rr1 comes before rr2
- *         +1 if rr2 comes before rr1
- */
-int ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2);
-
-/**
- * compares the wireformat of two rrs, contained in the given buffers.
- * \param[in] rr1_buf the first one
- * \param[in] rr2_buf the second one
- * \return 0 if equal
- *         -1 if rr1_buf comes before rr2_buf
- *         +1 if rr2_buf comes before rr1_buf
- */
-int ldns_rr_compare_wire(ldns_buffer *rr1_buf, ldns_buffer *rr2_buf);
-
-/**
- * returns true of the given rr's are equal.
- * Also returns true if one record is a DS that represents the
- * same DNSKEY record as the other record
- * \param[in] rr1 the first rr
- * \param[in] rr2 the second rr
- * \return true if equal otherwise false
- */
-bool ldns_rr_compare_ds(const ldns_rr *rr1, const ldns_rr *rr2);
-
-/**
- * compares two rr listss.
- * \param[in] rrl1 the first one
- * \param[in] rrl2 the second one
- * \return 0 if equal
- *         -1 if rrl1 comes before rrl2
- *         +1 if rrl2 comes before rrl1
- */
-int ldns_rr_list_compare(const ldns_rr_list *rrl1, const ldns_rr_list *rrl2);
-
-/** 
- * calculates the uncompressed size of an RR.
- * \param[in] r the rr to operate on
- * \return size of the rr
- */
-size_t ldns_rr_uncompressed_size(const ldns_rr *r);
-
-/** 
- * converts each dname in a rr to its canonical form.
- * \param[in] rr the rr to work on
- * \return void
- */
-void ldns_rr2canonical(ldns_rr *rr);
-
-/** 
- * converts each dname in each rr in a rr_list to its canonical form.
- * \param[in] rr_list the rr_list to work on
- * \return void
- */
-void ldns_rr_list2canonical(ldns_rr_list *rr_list);
-
-/** 
- * counts the number of labels of the ownername.
- * \param[in] rr count the labels of this rr
- * \return the number of labels
- */
-uint8_t ldns_rr_label_count(ldns_rr *rr);
-
-/**
- * returns the resource record descriptor for the given rr type.
- *
- * \param[in] type the type value of the rr type
- *\return the ldns_rr_descriptor for this type
- */
-const ldns_rr_descriptor *ldns_rr_descript(uint16_t type);
-
-/**
- * returns the minimum number of rdata fields of the rr type this descriptor describes.
- *
- * \param[in]  descriptor for an rr type
- * \return the minimum number of rdata fields
- */
-size_t ldns_rr_descriptor_minimum(const ldns_rr_descriptor *descriptor);
-
-/**
- * returns the maximum number of rdata fields of the rr type this descriptor describes.
- *
- * \param[in]  descriptor for an rr type
- * \return the maximum number of rdata fields
- */
-size_t ldns_rr_descriptor_maximum(const ldns_rr_descriptor *descriptor);
-
-/**
- * returns the rdf type for the given rdata field number of the rr type for the given descriptor.
- *
- * \param[in] descriptor for an rr type
- * \param[in] field the field number
- * \return the rdf type for the field
- */
-ldns_rdf_type ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor, size_t field);
-
-/**
- * Return the rr_list which matches the rdf at position field. Think
- * type-covered stuff for RRSIG
- * 
- * \param[in] l the rr_list to look in
- * \param[in] r the rdf to use for the comparison
- * \param[in] pos at which position can we find the rdf
- * 
- * \return a new rr list with only the RRs that match 
- *
- */
-ldns_rr_list *ldns_rr_list_subtype_by_rdf(ldns_rr_list *l, ldns_rdf *r, size_t pos);
-
-/**
- * convert an rdf of type LDNS_RDF_TYPE_TYPE to an actual
- * LDNS_RR_TYPE. This is usefull in the case when inspecting
- * the rrtype covered field of an RRSIG.
- * \param[in] rd the rdf to look at
- * \return a ldns_rr_type with equivalent LDNS_RR_TYPE
- *
- */
-ldns_rr_type    ldns_rdf2rr_type(const ldns_rdf *rd);
-
-/**
- * Returns the type of the first element of the RR
- * If there are no elements present, 0 is returned
- * 
- * \param[in] rr_list The rr list
- * \return rr_type of the first element, or 0 if the list is empty
- */
-ldns_rr_type
-ldns_rr_list_type(const ldns_rr_list *rr_list);
-
-/**
- * Returns the owner domain name rdf of the first element of the RR
- * If there are no elements present, NULL is returned
- * 
- * \param[in] rr_list The rr list
- * \return dname of the first element, or NULL if the list is empty
- */
-ldns_rdf *
-ldns_rr_list_owner(const ldns_rr_list *rr_list);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_RR_H */
diff --git a/include/ldns/rr_functions.h b/include/ldns/rr_functions.h
deleted file mode 100644
index 09a28dd..0000000
--- a/include/ldns/rr_functions.h
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * rr_functions.h
- *
- * the .h file with defs for the per rr
- * functions
- *
- * a Net::DNS like library for C
- * 
- * (c) NLnet Labs, 2005-2006
- * 
- * See the file LICENSE for the license
- */
-#ifndef LDNS_RR_FUNCTIONS_H
-#define LDNS_RR_FUNCTIONS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \file
- *
- * Defines some extra convenience functions for ldns_rr structures
- */
-
-/* A / AAAA */
-/**
- * returns the address of a LDNS_RR_TYPE_A rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the address or NULL on failure
- */
-ldns_rdf* ldns_rr_a_address(const ldns_rr *r);
-
-/**
- * sets the address of a LDNS_RR_TYPE_A rr
- * \param[in] r the rr to use
- * \param[in] f the address to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f);
-
-/* NS */
-/**
- * returns the name of a LDNS_RR_TYPE_NS rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the name or NULL on failure
- */
-ldns_rdf* ldns_rr_ns_nsdname(const ldns_rr *r);
-
-/* MX */
-/**
- * returns the mx pref. of a LDNS_RR_TYPE_MX rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the preference or NULL on failure
- */
-ldns_rdf* ldns_rr_mx_preference(const ldns_rr *r);
-/**
- * returns the mx host of a LDNS_RR_TYPE_MX rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the name of the MX host or NULL on failure
- */
-ldns_rdf* ldns_rr_mx_exchange(const ldns_rr *r);
-
-/* RRSIG */
-/**
- * returns the type covered of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the type covered or NULL on failure
- */
-ldns_rdf* ldns_rr_rrsig_typecovered(const ldns_rr *r);
-/**
- * sets the typecovered of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the typecovered to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the algorithm of a LDNS_RR_TYPE_RRSIG RR
- * \param[in] r the resource record
- * \return a ldns_rdf* with the algorithm or NULL on failure
- */
-ldns_rdf* ldns_rr_rrsig_algorithm(const ldns_rr *r);
-/**
- * sets the algorithm of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the algorithm to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the number of labels of a LDNS_RR_TYPE_RRSIG RR
- * \param[in] r the resource record
- * \return a ldns_rdf* with the number of labels or NULL on failure
- */
-ldns_rdf *ldns_rr_rrsig_labels(const ldns_rr *r);
-/**
- * sets the number of labels of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the number of labels to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the original TTL of a LDNS_RR_TYPE_RRSIG RR
- * \param[in] r the resource record
- * \return a ldns_rdf* with the original TTL or NULL on failure
- */
-ldns_rdf* ldns_rr_rrsig_origttl(const ldns_rr *r);
-/**
- * sets the original TTL of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the original TTL to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the expiration time of a LDNS_RR_TYPE_RRSIG RR
- * \param[in] r the resource record
- * \return a ldns_rdf* with the expiration time or NULL on failure
- */
-ldns_rdf* ldns_rr_rrsig_expiration(const ldns_rr *r);
-/**
- * sets the expireation date of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the expireation date to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the inception time of a LDNS_RR_TYPE_RRSIG RR
- * \param[in] r the resource record
- * \return a ldns_rdf* with the inception time or NULL on failure
- */
-ldns_rdf* ldns_rr_rrsig_inception(const ldns_rr *r);
-/**
- * sets the inception date of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the inception date to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the keytag of a LDNS_RR_TYPE_RRSIG RR
- * \param[in] r the resource record
- * \return a ldns_rdf* with the keytag or NULL on failure
- */
-ldns_rdf* ldns_rr_rrsig_keytag(const ldns_rr *r);
-/**
- * sets the keytag of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the keytag to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the signers name of a LDNS_RR_TYPE_RRSIG RR
- * \param[in] r the resource record
- * \return a ldns_rdf* with the signers name or NULL on failure
- */
-ldns_rdf* ldns_rr_rrsig_signame(const ldns_rr *r);
-/**
- * sets the signers name of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the signers name to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the signature data of a LDNS_RR_TYPE_RRSIG RR
- * \param[in] r the resource record
- * \return a ldns_rdf* with the signature data or NULL on failure
- */
-ldns_rdf* ldns_rr_rrsig_sig(const ldns_rr *r);
-/**
- * sets the signature data of a LDNS_RR_TYPE_RRSIG rr
- * \param[in] r the rr to use
- * \param[in] f the signature data to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f);
-
-/* DNSKEY */
-/**
- * returns the flags of a LDNS_RR_TYPE_DNSKEY rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the flags or NULL on failure
- */
-ldns_rdf* ldns_rr_dnskey_flags(const ldns_rr *r);
-/**
- * sets the flags of a LDNS_RR_TYPE_DNSKEY rr
- * \param[in] r the rr to use
- * \param[in] f the flags to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the protocol of a LDNS_RR_TYPE_DNSKEY rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the protocol or NULL on failure
- */
-ldns_rdf* ldns_rr_dnskey_protocol(const ldns_rr *r);
-/**
- * sets the protocol of a LDNS_RR_TYPE_DNSKEY rr
- * \param[in] r the rr to use
- * \param[in] f the protocol to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the algorithm of a LDNS_RR_TYPE_DNSKEY rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the algorithm or NULL on failure
- */
-ldns_rdf* ldns_rr_dnskey_algorithm(const ldns_rr *r);
-/**
- * sets the algorithm of a LDNS_RR_TYPE_DNSKEY rr
- * \param[in] r the rr to use
- * \param[in] f the algorithm to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f);
-/**
- * returns the key data of a LDNS_RR_TYPE_DNSKEY rr
- * \param[in] r the resource record
- * \return a ldns_rdf* with the key data or NULL on failure
- */
-ldns_rdf* ldns_rr_dnskey_key(const ldns_rr *r);
-/**
- * sets the key data of a LDNS_RR_TYPE_DNSKEY rr
- * \param[in] r the rr to use
- * \param[in] f the key data to set
- * \return true on success, false otherwise
- */
-bool ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f);
-
-/**
- * get the length of the keydata in bits
- * \param[in] keydata the raw key data
- * \param[in] len the length of the keydata
- * \param[in] alg the cryptographic algorithm this is a key for
- * \return the keysize in bits, or 0 on error
- */
-size_t ldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
-                                   const size_t len,
-                                   const ldns_algorithm alg);
-
-/**
- * get the length of the keydata in bits
- * \param[in] key the key rr to use
- * \return the keysize in bits
- */
-size_t ldns_rr_dnskey_key_size(const ldns_rr *key);
-
-/**
- * The type of function to be passed to ldns_rr_soa_increment_func,
- * ldns_rr_soa_increment_func_data or ldns_rr_soa_increment_int.
- * The function will be called with as the first argument the current serial
- * number of the SOA RR to be updated, and as the second argument a value
- * given when calling ldns_rr_soa_increment_func_data or 
- * ldns_rr_soa_increment_int. With ldns_rr_soa_increment_int the pointer
- * value holds the integer value passed to ldns_rr_soa_increment_int,
- * and it should be cast to intptr_t to be used as an integer by the
- * serial modifying function.
- */
-typedef uint32_t (*ldns_soa_serial_increment_func_t)(uint32_t, void*);
-
-/**
- * Function to be used with dns_rr_soa_increment_func_int, to set the soa
- * serial number. 
- * \param[in] unused the (unused) current serial number.
- * \param[in] data the serial number to be set.
- */
-uint32_t ldns_soa_serial_identity(uint32_t unused, void *data);
-
-/**
- * Function to be used with dns_rr_soa_increment_func, to increment the soa
- * serial number with one. 
- * \param[in] s the current serial number.
- * \param[in] unused unused.
- */
-uint32_t ldns_soa_serial_increment(uint32_t s, void *unused);
-
-/**
- * Function to be used with dns_rr_soa_increment_func_int, to increment the soa
- * serial number with a certain amount. 
- * \param[in] s the current serial number.
- * \param[in] data the amount to add to the current serial number.
- */
-uint32_t ldns_soa_serial_increment_by(uint32_t s, void *data);
-
-/**
- * Function to be used with ldns_rr_soa_increment_func or 
- * ldns_rr_soa_increment_func_int to set the soa serial to the number of 
- * seconds since unix epoch (1-1-1970 00:00). 
- * When data is given (i.e. the function is called via
- * ldns_rr_soa_increment_func_int), it is used as the current time. 
- * When the resulting serial number is smaller than the current serial number,
- * the current serial number is increased by one.
- * \param[in] s the current serial number.
- * \param[in] data the time in seconds since 1-1-1970 00:00
- */
-uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data);
-
-/**
- * Function to be used with ldns_rr_soa_increment_func or 
- * ldns_rr_soa_increment_func_int to set the soa serial to the current date
- * succeeded by a two digit iteration (datecounter).
- * When data is given (i.e. the function is called via
- * ldns_rr_soa_increment_func_int), it is used as the current time. 
- * When the resulting serial number is smaller than the current serial number,
- * the current serial number is increased by one.
- * \param[in] s the current serial number.
- * \param[in] data the time in seconds since 1-1-1970 00:00
- */
-uint32_t ldns_soa_serial_datecounter(uint32_t s, void *data);
-
-/**
- * Increment the serial number of the given SOA by one.
- * \param[in] soa The soa rr to be incremented
- */
-void ldns_rr_soa_increment(
-		ldns_rr *soa);
-
-/**
- * Increment the serial number of the given SOA with the given function.
- * Included functions to be used here are: ldns_rr_soa_increment, 
- * ldns_soa_serial_unixtime and ldns_soa_serial_datecounter.
- * \param[in] soa The soa rr to be incremented
- * \param[in] f the function to use to increment the soa rr.
- */
-void ldns_rr_soa_increment_func(
-		ldns_rr *soa, ldns_soa_serial_increment_func_t f);
-
-/**
- * Increment the serial number of the given SOA with the given function
- * passing it the given data argument.
- * \param[in] soa The soa rr to be incremented
- * \param[in] f the function to use to increment the soa rr.
- * \param[in] data this argument will be passed to f as the second argument.
- */
-void ldns_rr_soa_increment_func_data(
-		ldns_rr *soa, ldns_soa_serial_increment_func_t f, void *data);
-
-/**
- * Increment the serial number of the given SOA with the given function
- * using data as an argument for the function.
- * Included functions to be used here are: ldns_soa_serial_identity,
- * ldns_rr_soa_increment_by, ldns_soa_serial_unixtime and 
- * ldns_soa_serial_datecounter.
- * \param[in] soa The soa rr to be incremented
- * \param[in] f the function to use to increment the soa rr.
- * \param[in] data this argument will be passed to f as the second argument
- *                 (by casting it to void*).
- */
-void ldns_rr_soa_increment_func_int(
-		ldns_rr *soa, ldns_soa_serial_increment_func_t f, int data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_RR_FUNCTIONS_H */
diff --git a/include/ldns/sha1.h b/include/ldns/sha1.h
deleted file mode 100644
index d5b1082..0000000
--- a/include/ldns/sha1.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef LDNS_SHA1_H
-#define LDNS_SHA1_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- 
-#define LDNS_SHA1_BLOCK_LENGTH               64
-#define LDNS_SHA1_DIGEST_LENGTH              20
-
-typedef struct {
-        uint32_t       state[5];
-        uint64_t       count;
-        unsigned char   buffer[LDNS_SHA1_BLOCK_LENGTH];
-} ldns_sha1_ctx;
-  
-void ldns_sha1_init(ldns_sha1_ctx * context);
-void ldns_sha1_transform(uint32_t state[5], const unsigned char buffer[LDNS_SHA1_BLOCK_LENGTH]);
-void ldns_sha1_update(ldns_sha1_ctx *context, const unsigned char *data, unsigned int len);
-void ldns_sha1_final(unsigned char digest[LDNS_SHA1_DIGEST_LENGTH], ldns_sha1_ctx *context);
-
-/**
- * Convenience function to digest a fixed block of data at once.
- *
- * \param[in] data the data to digest
- * \param[in] data_len the length of data in bytes
- * \param[out] digest the length of data in bytes
- *             This pointer MUST have LDNS_SHA1_DIGEST_LENGTH bytes
- *             available
- * \return the SHA1 digest of the given data
- */
-unsigned char *ldns_sha1(unsigned char *data, unsigned int data_len, unsigned char *digest);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_SHA1_H */
diff --git a/include/ldns/sha2.h b/include/ldns/sha2.h
deleted file mode 100644
index 238767a..0000000
--- a/include/ldns/sha2.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * FILE:	sha2.h
- * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
- * 
- * Copyright (c) 2000-2001, Aaron D. Gifford
- * All rights reserved.
- *
- * Modified by Jelte Jansen to fit in ldns, and not clash with any
- * system-defined SHA code.
- * Changes:
- *  - Renamed (external) functions and constants to fit ldns style
- *  - Removed uintXX vs. u_intXX smartness, since ldns needs uintXX
- *    anyway
- *  - BYTE ORDER check replaced by simple ifdef as defined or not by
- *    configure.ac
- *  - Removed _End and _Data functions
- *  - Added ldns_shaX(data, len, digest) functions
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holder nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
- */
-
-#ifndef __LDNS_SHA2_H__
-#define __LDNS_SHA2_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Import u_intXX_t size_t type definitions from system headers.  You
- * may need to change this, or define these things yourself in this
- * file.
- */
-#include <sys/types.h>
-
-#if LDNS_BUILD_CONFIG_HAVE_INTTYPES_H
-
-#include <inttypes.h>
-
-#endif /* LDNS_BUILD_CONFIG_HAVE_INTTYPES_H */
-
-
-/*** SHA-256/384/512 Various Length Definitions ***********************/
-#define LDNS_SHA256_BLOCK_LENGTH		64
-#define LDNS_SHA256_DIGEST_LENGTH		32
-#define LDNS_SHA256_DIGEST_STRING_LENGTH	(LDNS_SHA256_DIGEST_LENGTH * 2 + 1)
-#define LDNS_SHA384_BLOCK_LENGTH		128
-#define LDNS_SHA384_DIGEST_LENGTH		48
-#define LDNS_SHA384_DIGEST_STRING_LENGTH	(LDNS_SHA384_DIGEST_LENGTH * 2 + 1)
-#define LDNS_SHA512_BLOCK_LENGTH		128
-#define LDNS_SHA512_DIGEST_LENGTH		64
-#define LDNS_SHA512_DIGEST_STRING_LENGTH	(LDNS_SHA512_DIGEST_LENGTH * 2 + 1)
-
-
-/*** SHA-256/384/512 Context Structures *******************************/
-
-typedef struct _ldns_sha256_CTX {
-	uint32_t	state[8];
-	uint64_t	bitcount;
-	uint8_t	buffer[LDNS_SHA256_BLOCK_LENGTH];
-} ldns_sha256_CTX;
-typedef struct _ldns_sha512_CTX {
-	uint64_t	state[8];
-	uint64_t	bitcount[2];
-	uint8_t	buffer[LDNS_SHA512_BLOCK_LENGTH];
-} ldns_sha512_CTX;
-
-typedef ldns_sha512_CTX ldns_sha384_CTX;
-
-
-/*** SHA-256/384/512 Function Prototypes ******************************/
-void ldns_sha256_init(ldns_sha256_CTX *);
-void ldns_sha256_update(ldns_sha256_CTX*, const uint8_t*, size_t);
-void ldns_sha256_final(uint8_t[LDNS_SHA256_DIGEST_LENGTH], ldns_sha256_CTX*);
-
-void ldns_sha384_init(ldns_sha384_CTX*);
-void ldns_sha384_update(ldns_sha384_CTX*, const uint8_t*, size_t);
-void ldns_sha384_final(uint8_t[LDNS_SHA384_DIGEST_LENGTH], ldns_sha384_CTX*);
-
-void ldns_sha512_init(ldns_sha512_CTX*);
-void ldns_sha512_update(ldns_sha512_CTX*, const uint8_t*, size_t);
-void ldns_sha512_final(uint8_t[LDNS_SHA512_DIGEST_LENGTH], ldns_sha512_CTX*);
-
-/**
- * Convenience function to digest a fixed block of data at once.
- *
- * \param[in] data the data to digest
- * \param[in] data_len the length of data in bytes
- * \param[out] digest the length of data in bytes
- *             This pointer MUST have LDNS_SHA256_DIGEST_LENGTH bytes
- *             available
- * \return the SHA1 digest of the given data
- */
-unsigned char *ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest);
-
-/**
- * Convenience function to digest a fixed block of data at once.
- *
- * \param[in] data the data to digest
- * \param[in] data_len the length of data in bytes
- * \param[out] digest the length of data in bytes
- *             This pointer MUST have LDNS_SHA384_DIGEST_LENGTH bytes
- *             available
- * \return the SHA1 digest of the given data
- */
-unsigned char *ldns_sha384(unsigned char *data, unsigned int data_len, unsigned char *digest);
-
-/**
- * Convenience function to digest a fixed block of data at once.
- *
- * \param[in] data the data to digest
- * \param[in] data_len the length of data in bytes
- * \param[out] digest the length of data in bytes
- *             This pointer MUST have LDNS_SHA512_DIGEST_LENGTH bytes
- *             available
- * \return the SHA1 digest of the given data
- */
-unsigned char *ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest);
-
-#ifdef	__cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __LDNS_SHA2_H__ */
diff --git a/include/ldns/str2host.h b/include/ldns/str2host.h
deleted file mode 100644
index d639970..0000000
--- a/include/ldns/str2host.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/**
- * str2host.h - conversion from str to the host fmt
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-#ifndef LDNS_2HOST_H
-#define LDNS_2HOST_H
-
-#include <ldns/common.h>
-#include <ldns/error.h>
-#include <ldns/rr.h>
-#include <ldns/rdata.h>
-#include <ldns/packet.h>
-#include <ldns/buffer.h>
-#include <ctype.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \file
- *
- * Defines functions to convert dns data in presentation format or text files
- * to internal structures.
- */
-
-/**
- * convert a byte into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] bytestr the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr);
-
-/**
- * convert a string to a int16 in wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] shortstr the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr);
-
-/**
- * convert a strings into a 4 byte int in wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] longstr the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr);
-
-/**
- * convert a time string to a time value in wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] time the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_time(ldns_rdf **rd, const char *time);
-
-/* convert string with NSEC3 salt to wireformat) 
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * return ldns_status
- */
-ldns_status ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *nsec3_salt);
-
-/* convert a time period (think TTL's) to wireformat) 
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * return ldns_status
- */
-ldns_status ldns_str2rdf_period(ldns_rdf **rd, const char *str);
-
-/**
- * convert str with an A record into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_a(ldns_rdf **rd, const char *str);
-
-/**
- * convert the str with an AAAA record into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str);
-
-/**
- * convert a string into wireformat (think txt record)
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted (NULL terminated)
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_str(ldns_rdf **rd, const char *str);
-
-/**
- * convert str with the apl record into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_apl(ldns_rdf **rd, const char *str);
-
-/**
- * convert the string with the b64 data into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_b64(ldns_rdf **rd, const char *str);
-
-/**
- * convert the string with the b32 ext hex data into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str);
-
-/**
- * convert a hex value into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_hex(ldns_rdf **rd, const char *str);
-
-/**
- * convert string with nsec into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_nsec(ldns_rdf **rd, const char *str);
-
-/**
- * convert a rrtype into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_type(ldns_rdf **rd, const char *str);
-
-/**
- * convert string with a classname into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_class(ldns_rdf **rd, const char *str);
-
-/**
- * convert an certificate algorithm value into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str);
-
-/**
- * convert an algorithm value into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_alg(ldns_rdf **rd, const char *str);
-
-/**
- * convert a tlsa certificate usage value into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_certificate_usage(ldns_rdf **rd, const char *str);
-
-/**
- * convert a tlsa selector value into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_selector(ldns_rdf **rd, const char *str);
-
-/**
- * convert a tlsa matching type value into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_matching_type(ldns_rdf **rd, const char *str);
-
-/**
- * convert a string with a unknown RR into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_unknown(ldns_rdf **rd, const char *str);
-
-/**
- * convert string with a protocol service into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_service(ldns_rdf **rd, const char *str);
-
-/**
- * convert a string with a LOC RR into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_loc(ldns_rdf **rd, const char *str);
-
-/**
- * convert string with a WKS RR into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_wks(ldns_rdf **rd, const char *str);
-
-/**
- * convert a str with a NSAP RR into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_nsap(ldns_rdf **rd, const char *str);
-
-/**
- * convert a str with a ATMA RR into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_atma(ldns_rdf **rd, const char *str);
-
-/**
- * convert a str with a IPSECKEY RR into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str);
-
-/**
- * convert a dname string into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_dname(ldns_rdf **rd, const char *str);
-
-/**
- * convert 4 * 16bit hex separated by colons into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_ilnp64(ldns_rdf **rd, const char *str);
-
-/**
- * convert 6 hex bytes separated by dashes into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_eui48(ldns_rdf **rd, const char *str);
-
-/**
- * convert 8 hex bytes separated by dashes into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_eui64(ldns_rdf **rd, const char *str);
-
-/**
- * Convert a non-zero sequence of US-ASCII letters and numbers into wireformat
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_tag(ldns_rdf **rd, const char *str);
-
-/**
- * Convert a <character-string> encoding of the value field as specified 
- * [RFC1035], Section 5.1., encoded as one bug chunk of data.
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_long_str(ldns_rdf **rd, const char *str);
-
-/**
- * Convert a "<algorithm> <hit> <pk>" encoding of the value field as specified 
- * in Section 6. of [RFC5205], encoded as wireformat as specified in Section 5.
- * of [RFC5205].
- * \param[in] rd the rdf where to put the data
- * \param[in] str the string to be converted
- * \return ldns_status
- */
-ldns_status ldns_str2rdf_hip(ldns_rdf **rd, const char *str);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_2HOST_H */
diff --git a/include/ldns/tsig.h b/include/ldns/tsig.h
deleted file mode 100644
index 676045f..0000000
--- a/include/ldns/tsig.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * tsig.h -- defines for TSIG [RFC2845]
- *
- * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- */
-
-#ifndef LDNS_TSIG_H
-#define LDNS_TSIG_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \file
- *
- * Defines functions for TSIG usage
- */
-
-
-/**
- * Contains credentials for TSIG
-*/
-typedef struct ldns_tsig_credentials_struct
-{
-    char *algorithm;
-    char *keyname;
-    char *keydata;
-    /* XXX More eventually. */
-} ldns_tsig_credentials;
-
-char *ldns_tsig_algorithm(ldns_tsig_credentials *);
-char *ldns_tsig_keyname(ldns_tsig_credentials *);
-char *ldns_tsig_keydata(ldns_tsig_credentials *);
-char *ldns_tsig_keyname_clone(ldns_tsig_credentials *);
-char *ldns_tsig_keydata_clone(ldns_tsig_credentials *);
-
-/**
- * verifies the tsig rr for the given packet and key.
- * The wire must be given too because tsig does not sign normalized packets.
- * \param[in] pkt the packet to verify
- * \param[in] wire needed to verify the mac
- * \param[in] wire_size size of wire
- * \param[in] key_name the name of the shared key
- * \param[in] key_data the key in base 64 format
- * \param[in] mac original mac
- * \return true if tsig is correct, false if not, or if tsig is not set
- */
-bool ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, ldns_rdf *mac);
-
-/**
- * verifies the tsig rr for the given packet and key.
- * The wire must be given too because tsig does not sign normalized packets.
- * \param[in] pkt the packet to verify
- * \param[in] wire needed to verify the mac
- * \param[in] wire_size size of wire
- * \param[in] key_name the name of the shared key
- * \param[in] key_data the key in base 64 format
- * \param[in] mac original mac
- * \param[in] tsig_timers_only must be zero for the first packet and positive for subsequent packets. If zero, all digest
-   components are used to verify the _mac. If non-zero, only the TSIG timers are used to verify the mac.
- * \return true if tsig is correct, false if not, or if tsig is not set
- */
-bool ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, ldns_rdf *mac,
-    int tsig_timers_only);
-
-/**
- * creates a tsig rr for the given packet and key.
- * \param[in] pkt the packet to sign
- * \param[in] key_name the name of the shared key
- * \param[in] key_data the key in base 64 format
- * \param[in] fudge seconds of error permitted in time signed
- * \param[in] algorithm_name the name of the algorithm used
- * \param[in] query_mac is added to the digest if not NULL (so NULL is for signing queries, not NULL is for signing answers)
- * \return status (OK if success)
- */
-ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge,
-    const char *algorithm_name, ldns_rdf *query_mac);
-
-/**
- * creates a tsig rr for the given packet and key.
- * \param[in] pkt the packet to sign
- * \param[in] key_name the name of the shared key
- * \param[in] key_data the key in base 64 format
- * \param[in] fudge seconds of error permitted in time signed
- * \param[in] algorithm_name the name of the algorithm used
- * \param[in] query_mac is added to the digest if not NULL (so NULL is for signing queries, not NULL is for signing answers)
- * \param[in] tsig_timers_only must be zero for the first packet and positive for subsequent packets. If zero, all digest
-   components are used to create the query_mac. If non-zero, only the TSIG timers are used to create the query_mac.
- * \return status (OK if success)
- */
-ldns_status ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge,
-    const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_TSIG_H */
diff --git a/include/ldns/update.h b/include/ldns/update.h
deleted file mode 100644
index d3459d3..0000000
--- a/include/ldns/update.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * update.h
- *
- * Functions for RFC 2136 Dynamic Update
- *
- * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- */
-
-/**
- * \file
- *
- * Defines functions to perform UPDATE queries
- */
-
-
-#ifndef LDNS_UPDATE_H
-#define LDNS_UPDATE_H
-
-#include <ldns/resolver.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * create an update packet from zone name, class and the rr lists
- * \param[in] zone_rdf name of the zone
- * \param[in] clas zone class
- * \param[in] pr_rrlist list of Prerequisite Section RRs
- * \param[in] up_rrlist list of Updates Section RRs
- * \param[in] ad_rrlist list of Additional Data Section RRs (currently unused)
- * \return the new packet
- */
-ldns_pkt *ldns_update_pkt_new(ldns_rdf *zone_rdf, ldns_rr_class clas, ldns_rr_list *pr_rrlist, ldns_rr_list *up_rrlist, ldns_rr_list *ad_rrlist);
-
-/**
- * add tsig credentials to
- * a packet from a resolver
- * \param[in] p packet to copy to
- * \param[in] r resolver to copy from
- *
- * \return status wether successfull or not
- */
-ldns_status ldns_update_pkt_tsig_add(ldns_pkt *p, ldns_resolver *r);
-
-/* access functions */
-
-/**
- * Get the zo count
- * \param[in] p the packet
- * \return the zo count
- */
-uint16_t ldns_update_zocount(const ldns_pkt *p);
-/**
- * Get the zo count
- * \param[in] p the packet
- * \return the pr count
- */
-uint16_t ldns_update_prcount(const ldns_pkt *p);
-/**
- * Get the zo count
- * \param[in] p the packet
- * \return the up count
- */
-uint16_t ldns_update_upcount(const ldns_pkt *p);
-/**
- * Get the zo count
- * \param[in] p the packet
- * \return the ad count
- */
-uint16_t ldns_update_ad(const ldns_pkt *p);
-/**
- * Set the zo count
- * \param[in] p the packet
- * \param[in] c the zo count to set
- */
-void ldns_update_set_zo(ldns_pkt *p, uint16_t c);
-/**
- * Set the pr count
- * \param[in] p the packet
- * \param[in] c the pr count to set
- */
-void ldns_update_set_prcount(ldns_pkt *p, uint16_t c);
-/**
- * Set the up count
- * \param[in] p the packet
- * \param[in] c the up count to set
- */
-void ldns_update_set_upcount(ldns_pkt *p, uint16_t c);
-/**
- * Set the ad count
- * \param[in] p the packet
- * \param[in] c the ad count to set
- */
-void ldns_update_set_adcount(ldns_pkt *p, uint16_t c);
-
-/* soa functions that need to be configured */
-/*
- * Not sure if we want to keep these like this, therefore
- * not documented
- */
-ldns_status ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r, ldns_rr_class c, ldns_rdf **mname);
-/* 
- * Not sure if we want to keep these like this, therefore
- * not documented
- */
-ldns_status ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, ldns_rr_class c, ldns_rdf **zone_rdf, ldns_rdf **mname_rdf);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* LDNS_UPDATE_H */
diff --git a/include/ldns/util.h b/include/ldns/util.h
deleted file mode 100644
index 86848eb..0000000
--- a/include/ldns/util.h
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * util.h
- *  
- * helper function header file
- * 
- * a Net::DNS like library for C
- * 
- * (c) NLnet Labs, 2004
- * 
- * See the file LICENSE for the license
- */
-
-#ifndef _UTIL_H
-#define _UTIL_H
-
-#include "EXTERN.h"
-#include "perl.h"
-#include <ldns/common.h>
-#include <time.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define dprintf(X,Y) fprintf(stderr, (X), (Y))
-/* #define	dprintf(X, Y)  */
-
-#define LDNS_VERSION "1.6.18"
-#define LDNS_REVISION ((1<<16)|(6<<8)|(18))
-
-/**
- * splint static inline workaround
- */
-#ifdef S_SPLINT_S
-#  define INLINE 
-#else
-#  ifdef SWIG
-#    define INLINE static
-#  else
-#    define INLINE static inline
-#  endif
-#endif
-
-/**
- * Memory management macros
- */
-#define LDNS_MALLOC(type)		LDNS_XMALLOC(type, 1)
-
-#define LDNS_XMALLOC(type, count)	((type *) malloc((count) * sizeof(type)))
-
-#define LDNS_CALLOC(type, count)	((type *) calloc((count), sizeof(type)))
-
-#define LDNS_REALLOC(ptr, type)		LDNS_XREALLOC((ptr), type, 1)
-
-#define LDNS_XREALLOC(ptr, type, count)				\
-	((type *) realloc((ptr), (count) * sizeof(type)))
-
-#define LDNS_FREE(ptr) \
-	do { free((ptr)); (ptr) = NULL; } while (0)
-
-#define LDNS_DEP     printf("DEPRECATED FUNCTION!\n");
-
-/*
- * Copy data allowing for unaligned accesses in network byte order
- * (big endian).
- */
-INLINE uint16_t
-ldns_read_uint16(const void *src)
-{
-#ifdef ALLOW_UNALIGNED_ACCESSES
-	return ntohs(*(const uint16_t *) src);
-#else
-	const uint8_t *p = (const uint8_t *) src;
-	return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
-#endif
-}
-
-INLINE uint32_t
-ldns_read_uint32(const void *src)
-{
-#ifdef ALLOW_UNALIGNED_ACCESSES
-	return ntohl(*(const uint32_t *) src);
-#else
-	const uint8_t *p = (const uint8_t *) src;
-	return (  ((uint32_t) p[0] << 24)
-		| ((uint32_t) p[1] << 16)
-		| ((uint32_t) p[2] << 8)
-		|  (uint32_t) p[3]);
-#endif
-}
-
-/*
- * Copy data allowing for unaligned accesses in network byte order
- * (big endian).
- */
-INLINE void
-ldns_write_uint16(void *dst, uint16_t data)
-{
-#ifdef ALLOW_UNALIGNED_ACCESSES
-	* (uint16_t *) dst = htons(data);
-#else
-	uint8_t *p = (uint8_t *) dst;
-	p[0] = (uint8_t) ((data >> 8) & 0xff);
-	p[1] = (uint8_t) (data & 0xff);
-#endif
-}
-
-INLINE void
-ldns_write_uint32(void *dst, uint32_t data)
-{
-#ifdef ALLOW_UNALIGNED_ACCESSES
-	* (uint32_t *) dst = htonl(data);
-#else
-	uint8_t *p = (uint8_t *) dst;
-	p[0] = (uint8_t) ((data >> 24) & 0xff);
-	p[1] = (uint8_t) ((data >> 16) & 0xff);
-	p[2] = (uint8_t) ((data >> 8) & 0xff);
-	p[3] = (uint8_t) (data & 0xff);
-#endif
-}
-
-/* warning. */
-INLINE void
-ldns_write_uint64_as_uint48(void *dst, uint64_t data)
-{
-	uint8_t *p = (uint8_t *) dst;
-	p[0] = (uint8_t) ((data >> 40) & 0xff);
-	p[1] = (uint8_t) ((data >> 32) & 0xff);
-	p[2] = (uint8_t) ((data >> 24) & 0xff);
-	p[3] = (uint8_t) ((data >> 16) & 0xff);
-	p[4] = (uint8_t) ((data >> 8) & 0xff);
-	p[5] = (uint8_t) (data & 0xff);
-}
-
-
-/**
- * Structure to do a Schwartzian-like transformation, for instance when
- * sorting. If you need a transformation on the objects that are sorted,
- * you can sue this to store the transformed values, so you do not
- * need to do the transformation again for each comparison
- */
-struct ldns_schwartzian_compare_struct {
-	void *original_object;
-	void *transformed_object;
-};
-
-/** A general purpose lookup table
- *  
- *  Lookup tables are arrays of (id, name) pairs,
- *  So you can for instance lookup the RCODE 3, which is "NXDOMAIN",
- *  and vice versa. The lookup tables themselves are defined wherever needed,
- *  for instance in \ref host2str.c
- */
-struct ldns_struct_lookup_table {
-        int id;
-        const char *name;
-};
-typedef struct ldns_struct_lookup_table ldns_lookup_table;
-  
-/**
- * Looks up the table entry by name, returns NULL if not found.
- * \param[in] table the lookup table to search in
- * \param[in] name what to search for
- * \return the item found
- */
-ldns_lookup_table *ldns_lookup_by_name(ldns_lookup_table table[],
-                                       const char *name);
-
-/**
- * Looks up the table entry by id, returns NULL if not found.
- * \param[in] table the lookup table to search in
- * \param[in] id what to search for
- * \return the item found
- */
-ldns_lookup_table *ldns_lookup_by_id(ldns_lookup_table table[], int id);
-
-/**
- * Returns the value of the specified bit
- * The bits are counted from left to right, so bit #0 is the
- * left most bit.
- * \param[in] bits array holding the bits
- * \param[in] index to the wanted bit
- * \return 
- */
-int ldns_get_bit(uint8_t bits[], size_t index);
-
-
-/**
- * Returns the value of the specified bit
- * The bits are counted from right to left, so bit #0 is the
- * right most bit.
- * \param[in] bits array holding the bits
- * \param[in] index to the wanted bit
- * \return 1 or 0 depending no the bit state
- */
-int ldns_get_bit_r(uint8_t bits[], size_t index);
-
-/**
- * sets the specified bit in the specified byte to
- * 1 if value is true, 0 if false
- * The bits are counted from right to left, so bit #0 is the
- * right most bit.
- * \param[in] byte the bit to set the bit in
- * \param[in] bit_nr the bit to set (0 <= n <= 7)
- * \param[in] value whether to set the bit to 1 or 0
- * \return 1 or 0 depending no the bit state
- */
-void ldns_set_bit(uint8_t *byte, int bit_nr, bool value);
-
-/**
- * Returns the value of a to the power of b
- * (or 1 of b < 1)
- */
-/*@unused@*/
-INLINE long
-ldns_power(long a, long b) {
-	long result = 1;
-	while (b > 0) {
-		if (b & 1) {
-			result *= a;
-			if (b == 1) {
-				return result;
-			}
-		}
-		a *= a;
-		b /= 2;
-	}
-	return result;
-}
-
-/**
- * Returns the int value of the given (hex) digit
- * \param[in] ch the hex char to convert
- * \return the converted decimal value
- */
-int ldns_hexdigit_to_int(char ch);
-
-/**
- * Returns the char (hex) representation of the given int
- * \param[in] ch the int to convert
- * \return the converted hex char
- */
-char ldns_int_to_hexdigit(int ch);
-
-/**
- * Converts a hex string to binary data
- *
- * \param[out] data The binary result is placed here.
- * At least strlen(str)/2 bytes should be allocated
- * \param[in] str The hex string to convert.
- * This string should not contain spaces
- * \return The number of bytes of converted data, or -1 if one of the arguments * is NULL, or -2 if the string length is not an even number
- */
-int
-ldns_hexstring_to_data(uint8_t *data, const char *str);
-
-/**
- * Show the internal library version
- * \return a string with the version in it
- */
-const char * ldns_version(void);
-
-/**
- * Convert TM to seconds since epoch (midnight, January 1st, 1970).
- * Like timegm(3), which is not always available.
- * \param[in] tm a struct tm* with the date
- * \return the seconds since epoch
- */
-time_t ldns_mktime_from_utc(const struct tm *tm);
-
-time_t mktime_from_utc(const struct tm *tm);
-
-/**
- * The function interprets time as the number of seconds since epoch
- * with respect to now using serial arithmitics (rfc1982).
- * That number of seconds is then converted to broken-out time information.
- * This is especially usefull when converting the inception and expiration
- * fields of RRSIG records.
- *
- * \param[in] time number of seconds since epoch (midnight, January 1st, 1970)
- *            to be intepreted as a serial arithmitics number relative to now.
- * \param[in] now number of seconds since epoch (midnight, January 1st, 1970)
- *            to which the time value is compared to determine the final value.
- * \param[out] result the struct with the broken-out time information
- * \return result on success or NULL on error
- */
-struct tm * ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result);
- 
-/**
- * Seed the random function.
- * If the file descriptor is specified, the random generator is seeded with
- * data from that file. If not, /dev/urandom is used.
- *
- * applications should call this if they need entropy data within ldns
- * If openSSL is available, it is automatically seeded from /dev/urandom
- * or /dev/random.
- *
- * If you need more entropy, or have no openssl available, this function
- * MUST be called at the start of the program
- *
- * If openssl *is* available, this function just adds more entropy
- *
- * \param[in] fd a file providing entropy data for the seed
- * \param[in] size the number of bytes to use as entropy data. If this is 0,
- *            only the minimal amount is taken (usually 4 bytes)
- * \return 0 if seeding succeeds, 1 if it fails
- */
-int ldns_init_random(FILE *fd, unsigned int size);
-
-/**
- * Get random number.
- * \return random number.
- *
- */
-uint16_t ldns_get_random(void);
-
-/**
- * Encode data as BubbleBabble
- *
- * \param[in] data a pointer to data to be encoded
- * \param[in] len size the number of bytes of data
- * \return a string of BubbleBabble
- */
-char *ldns_bubblebabble(uint8_t *data, size_t len);
-
-
-INLINE time_t ldns_time(time_t *t) { return time(t); }
-
-
-/**
- * calculates the size needed to store the result of b32_ntop
- */
-/*@unused@*/
-INLINE size_t ldns_b32_ntop_calculate_size(size_t src_data_length)
-{
-	return src_data_length == 0 ? 0 : ((src_data_length - 1) / 5 + 1) * 8;
-}
-
-INLINE size_t ldns_b32_ntop_calculate_size_no_padding(size_t src_data_length)
-{
-	return ((src_data_length + 3) * 8 / 5) - 4;
-}
-
-int ldns_b32_ntop(const uint8_t* src_data, size_t src_data_length,
-	     char* target_text_buffer, size_t target_text_buffer_size);
-
-int ldns_b32_ntop_extended_hex(const uint8_t* src_data, size_t src_data_length,
-	     char* target_text_buffer, size_t target_text_buffer_size);
-
-#if ! LDNS_BUILD_CONFIG_HAVE_B32_NTOP
-
-int b32_ntop(const uint8_t* src_data, size_t src_data_length,
-	     char* target_text_buffer, size_t target_text_buffer_size);
-
-int b32_ntop_extended_hex(const uint8_t* src_data, size_t src_data_length,
-	     char* target_text_buffer, size_t target_text_buffer_size);
-
-#endif /* ! LDNS_BUILD_CONFIG_HAVE_B32_NTOP */
-
-
-/**
- * calculates the size needed to store the result of b32_pton
- */
-/*@unused@*/
-INLINE size_t ldns_b32_pton_calculate_size(size_t src_text_length)
-{
-	return src_text_length * 5 / 8;
-}
-
-int ldns_b32_pton(const char* src_text, size_t src_text_length,
-	       	uint8_t* target_data_buffer, size_t target_data_buffer_size);
-
-int ldns_b32_pton_extended_hex(const char* src_text, size_t src_text_length,
-		uint8_t* target_data_buffer, size_t target_data_buffer_size);
-
-#if ! LDNS_BUILD_CONFIG_HAVE_B32_PTON
-
-int b32_pton(const char* src_text, size_t src_text_length,
-	       	uint8_t* target_data_buffer, size_t target_data_buffer_size);
-
-int b32_pton_extended_hex(const char* src_text, size_t src_text_length,
-		uint8_t* target_data_buffer, size_t target_data_buffer_size);
-
-#endif /* ! LDNS_BUILD_CONFIG_HAVE_B32_PTON */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* !_UTIL_H */
diff --git a/include/ldns/wire2host.h b/include/ldns/wire2host.h
deleted file mode 100644
index 53155b3..0000000
--- a/include/ldns/wire2host.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * wire2host.h - from wire conversion routines
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file
- *
- * Contains functions that translate dns data from the wire format (as sent
- * by servers and clients) to the internal structures.
- */
- 
-#ifndef LDNS_WIRE2HOST_H
-#define LDNS_WIRE2HOST_H
-
-#include <ldns/rdata.h>
-#include <ldns/common.h>
-#include <ldns/error.h>
-#include <ldns/rr.h>
-#include <ldns/packet.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The length of the header */
-#define	LDNS_HEADER_SIZE	12
-
-/* First octet of flags */
-#define	LDNS_RD_MASK		0x01U
-#define	LDNS_RD_SHIFT	0
-#define	LDNS_RD_WIRE(wirebuf)	(*(wirebuf+2) & LDNS_RD_MASK)
-#define	LDNS_RD_SET(wirebuf)	(*(wirebuf+2) |= LDNS_RD_MASK)
-#define	LDNS_RD_CLR(wirebuf)	(*(wirebuf+2) &= ~LDNS_RD_MASK)
-
-#define LDNS_TC_MASK		0x02U
-#define LDNS_TC_SHIFT	1
-#define	LDNS_TC_WIRE(wirebuf)	(*(wirebuf+2) & LDNS_TC_MASK)
-#define	LDNS_TC_SET(wirebuf)	(*(wirebuf+2) |= LDNS_TC_MASK)
-#define	LDNS_TC_CLR(wirebuf)	(*(wirebuf+2) &= ~LDNS_TC_MASK)
-
-#define	LDNS_AA_MASK		0x04U
-#define	LDNS_AA_SHIFT	2
-#define	LDNS_AA_WIRE(wirebuf)	(*(wirebuf+2) & LDNS_AA_MASK)
-#define	LDNS_AA_SET(wirebuf)	(*(wirebuf+2) |= LDNS_AA_MASK)
-#define	LDNS_AA_CLR(wirebuf)	(*(wirebuf+2) &= ~LDNS_AA_MASK)
-
-#define	LDNS_OPCODE_MASK	0x78U
-#define	LDNS_OPCODE_SHIFT	3
-#define	LDNS_OPCODE_WIRE(wirebuf)	((*(wirebuf+2) & LDNS_OPCODE_MASK) >> LDNS_OPCODE_SHIFT)
-#define	LDNS_OPCODE_SET(wirebuf, opcode) \
-	(*(wirebuf+2) = ((*(wirebuf+2)) & ~LDNS_OPCODE_MASK) | ((opcode) << LDNS_OPCODE_SHIFT))
-
-#define	LDNS_QR_MASK		0x80U
-#define	LDNS_QR_SHIFT	7
-#define	LDNS_QR_WIRE(wirebuf)	(*(wirebuf+2) & LDNS_QR_MASK)
-#define	LDNS_QR_SET(wirebuf)	(*(wirebuf+2) |= LDNS_QR_MASK)
-#define	LDNS_QR_CLR(wirebuf)	(*(wirebuf+2) &= ~LDNS_QR_MASK)
-
-/* Second octet of flags */
-#define	LDNS_RCODE_MASK	0x0fU
-#define	LDNS_RCODE_SHIFT	0
-#define	LDNS_RCODE_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_RCODE_MASK)
-#define	LDNS_RCODE_SET(wirebuf, rcode) \
-	(*(wirebuf+3) = ((*(wirebuf+3)) & ~LDNS_RCODE_MASK) | (rcode))
-
-#define	LDNS_CD_MASK		0x10U
-#define	LDNS_CD_SHIFT	4
-#define	LDNS_CD_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_CD_MASK)
-#define	LDNS_CD_SET(wirebuf)	(*(wirebuf+3) |= LDNS_CD_MASK)
-#define	LDNS_CD_CLR(wirebuf)	(*(wirebuf+3) &= ~LDNS_CD_MASK)
-
-#define	LDNS_AD_MASK		0x20U
-#define	LDNS_AD_SHIFT	5
-#define	LDNS_AD_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_AD_MASK)
-#define	LDNS_AD_SET(wirebuf)	(*(wirebuf+3) |= LDNS_AD_MASK)
-#define	LDNS_AD_CLR(wirebuf)	(*(wirebuf+3) &= ~LDNS_AD_MASK)
-
-#define	LDNS_Z_MASK		0x40U
-#define	LDNS_Z_SHIFT		6
-#define	LDNS_Z_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_Z_MASK)
-#define	LDNS_Z_SET(wirebuf)	(*(wirebuf+3) |= LDNS_Z_MASK)
-#define	LDNS_Z_CLR(wirebuf)	(*(wirebuf+3) &= ~LDNS_Z_MASK)
-
-#define	LDNS_RA_MASK		0x80U
-#define	LDNS_RA_SHIFT	7
-#define	LDNS_RA_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_RA_MASK)
-#define	LDNS_RA_SET(wirebuf)	(*(wirebuf+3) |= LDNS_RA_MASK)
-#define	LDNS_RA_CLR(wirebuf)	(*(wirebuf+3) &= ~LDNS_RA_MASK)
-
-/* Query ID */
-#define	LDNS_ID_WIRE(wirebuf)		(ldns_read_uint16(wirebuf))
-#define	LDNS_ID_SET(wirebuf, id)	(ldns_write_uint16(wirebuf, id))
-
-/* Counter of the question section */
-#define LDNS_QDCOUNT_OFF		4
-/*
-#define	QDCOUNT(wirebuf)		(ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
-*/
-#define	LDNS_QDCOUNT(wirebuf)		(ldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF))
-
-/* Counter of the answer section */
-#define LDNS_ANCOUNT_OFF		6
-#define	LDNS_ANCOUNT(wirebuf)		(ldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF))
-
-/* Counter of the authority section */
-#define LDNS_NSCOUNT_OFF		8
-#define	LDNS_NSCOUNT(wirebuf)		(ldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF))
-
-/* Counter of the additional section */
-#define LDNS_ARCOUNT_OFF		10
-#define	LDNS_ARCOUNT(wirebuf)		(ldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF))
-
-/**
- * converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
- * This function will initialize and allocate memory space for the packet 
- * structure.
- * 
- * \param[in] packet pointer to the structure to hold the packet
- * \param[in] data pointer to the buffer with the data
- * \param[in] len the length of the data buffer (in bytes)
- * \return LDNS_STATUS_OK if everything succeeds, error otherwise
- */
-ldns_status ldns_wire2pkt(ldns_pkt **packet, const uint8_t *data, size_t len);
-
-/**
- * converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
- * This function will initialize and allocate memory space for the packet 
- * structure.
- * 
- * \param[in] packet pointer to the structure to hold the packet
- * \param[in] buffer the buffer with the data
- * \return LDNS_STATUS_OK if everything succeeds, error otherwise
- */
-ldns_status ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer);
-
-/**
- * converts the data on the uint8_t bytearray (in wire format) to a DNS 
- * dname rdata field. This function will initialize and allocate memory
- * space for the dname structure. The length of the wiredata of this rdf 
- * is added to the *pos value.
- *
- * \param[in] dname pointer to the structure to hold the rdata value
- * \param[in] wire pointer to the buffer with the data
- * \param[in] max the length of the data buffer (in bytes)
- * \param[in] pos the position of the rdf in the buffer (ie. the number of bytes 
- *            from the start of the buffer)
- * \return LDNS_STATUS_OK if everything succeeds, error otherwise
- */
-ldns_status ldns_wire2dname(ldns_rdf **dname, const uint8_t *wire, size_t max, size_t *pos);
-
-/**
- * converts the data on the uint8_t bytearray (in wire format) to DNS 
- * rdata fields, and adds them to the list of rdfs of the given rr.
- * This function will initialize and allocate memory space for the dname
- * structures.
- * The length of the wiredata of these rdfs is added to the *pos value.
- *
- * All rdfs belonging to the RR are read; the rr should have no rdfs
- * yet. An error is returned if the format cannot be parsed.
- *
- * \param[in] rr pointer to the ldns_rr structure to hold the rdata value
- * \param[in] wire pointer to the buffer with the data
- * \param[in] max the length of the data buffer (in bytes)
- * \param[in] pos the position of the rdf in the buffer (ie. the number of bytes 
- *            from the start of the buffer)
- * \return LDNS_STATUS_OK if everything succeeds, error otherwise
- */
-ldns_status ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos);
-
-/**
- * converts the data on the uint8_t bytearray (in wire format) to a DNS 
- * resource record.
- * This function will initialize and allocate memory space for the rr
- * structure.
- * The length of the wiredata of this rr is added to the *pos value.
- * 
- * \param[in] rr pointer to the structure to hold the rdata value
- * \param[in] wire pointer to the buffer with the data
- * \param[in] max the length of the data buffer (in bytes)
- * \param[in] pos the position of the rr in the buffer (ie. the number of bytes 
- *            from the start of the buffer)
- * \param[in] section the section in the packet the rr is meant for
- * \return LDNS_STATUS_OK if everything succeeds, error otherwise
- */
-ldns_status ldns_wire2rr(ldns_rr **rr, const uint8_t *wire, size_t max, size_t *pos, ldns_pkt_section section);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_WIRE2HOST_H */
diff --git a/include/ldns/zone.h b/include/ldns/zone.h
deleted file mode 100644
index 0d129a0..0000000
--- a/include/ldns/zone.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * zone.h
- *
- * zone definitions
- *  - what is it
- *  - get_glue function
- *  - search etc
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- *
- * See the file LICENSE for the license
- */
-
-/**
- * \file
- *
- * Defines the ldns_zone structure and functions to manipulate it.
- */
- 
-
-#ifndef LDNS_ZONE_H
-#define LDNS_ZONE_H
-
-#include <ldns/common.h>
-#include <ldns/rdata.h>
-#include <ldns/rr.h>
-#include <ldns/error.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** 
- * DNS Zone
- *
- * A list of RR's with some
- * extra information which comes from the SOA RR
- * Note: nothing has been done to make this efficient (yet).
- */
-struct ldns_struct_zone
-{
-	/** the soa defines a zone */
-	ldns_rr 	*_soa;
-	/* basicly a zone is a list of rr's */
-	ldns_rr_list 	*_rrs;
-	/* we could change this to be a b-tree etc etc todo */
-};
-typedef struct ldns_struct_zone ldns_zone;	
-	
-/**
- * create a new ldns_zone structure
- * \return a pointer to a ldns_zone structure
- */
-ldns_zone * ldns_zone_new(void);
-
-/**
- * Return the soa record of a zone
- * \param[in] z the zone to read from
- * \return the soa record in the zone
- */
-ldns_rr * ldns_zone_soa(const ldns_zone *z);
-
-/**
- * Returns the number of resource records in the zone, NOT counting the SOA record
- * \param[in] z the zone to read from
- * \return the number of rr's in the zone
- */
-size_t ldns_zone_rr_count(const ldns_zone *z);
-
-/**
- * Set the zone's soa record
- * \param[in] z the zone to put the new soa in
- * \param[in] soa the soa to set
- */
-void ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa);
-
-/**
- * Get a list of a zone's content. Note that the SOA
- * isn't included in this list. You need to get the 
- * with ldns_zone_soa.
- * \param[in] z the zone to read from
- * \return the rrs from this zone
- */
-ldns_rr_list * ldns_zone_rrs(const ldns_zone *z);
-
-/**
- * Set the zone's contents
- * \param[in] z the zone to put the new soa in
- * \param[in] rrlist the rrlist to use
- */
-void ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist);
-
-/**
- * push an rrlist to a zone structure. This function use pointer
- * copying, so the rr_list structure inside z is modified!
- * \param[in] z the zone to add to
- * \param[in] list the list to add
- * \return a true on succes otherwise falsed
- */
-bool ldns_zone_push_rr_list(ldns_zone *z, ldns_rr_list *list);
-
-/**
- * push an single rr to a zone structure. This function use pointer
- * copying, so the rr_list structure inside z is modified!
- * \param[in] z the zone to add to
- * \param[in] rr the rr to add
- * \return a true on succes otherwise falsed
- */
-bool ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr);
-
-/**
- * Retrieve all resource records from the zone that are glue
- * records. The resulting list does are pointer references
- * to the zone's data.
- *
- * Due to the current zone implementation (as a list of rr's), this
- * function is extremely slow. Another (probably better) way to do this
- * is to use an ldns_dnssec_zone structure and the 
- * ldns_dnssec_mark_and_get_glue() function.
- *
- * \param[in] z the zone to look for glue
- * \return the rr_list with the glue
- */
-ldns_rr_list *ldns_zone_glue_rr_list(const ldns_zone *z);
-
-/**
- * Create a new zone from a file
- * \param[out] z the new zone
- * \param[in] *fp the filepointer to use
- * \param[in] *origin the zones' origin
- * \param[in] ttl default ttl to use
- * \param[in] c default class to use (IN)
- *
- * \return ldns_status mesg with an error or LDNS_STATUS_OK
- */
-ldns_status ldns_zone_new_frm_fp(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c);
-
-/**
- * Create a new zone from a file, keep track of the line numbering
- * \param[out] z the new zone
- * \param[in] *fp the filepointer to use
- * \param[in] *origin the zones' origin
- * \param[in] ttl default ttl to use
- * \param[in] c default class to use (IN)
- * \param[out] line_nr used for error msg, to get to the line number
- *
- * \return ldns_status mesg with an error or LDNS_STATUS_OK
- */
-ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c, int *line_nr);
-
-/**
- * Frees the allocated memory for the zone, and the rr_list structure in it
- * \param[in] zone the zone to free
- */
-void ldns_zone_free(ldns_zone *zone);
-
-/**
- * Frees the allocated memory for the zone, the soa rr in it, 
- * and the rr_list structure in it, including the rr's in that. etc.
- * \param[in] zone the zone to free
- */
-void ldns_zone_deep_free(ldns_zone *zone);
-
-/**
- * Sort the rrs in a zone, with the current impl. this is slow
- * \param[in] zone the zone to sort
- */
-void ldns_zone_sort(ldns_zone *zone);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LDNS_ZONE_H */
diff --git a/ldns/include/ldns/buffer.h b/ldns/include/ldns/buffer.h
new file mode 100644
index 0000000..3b64198
--- /dev/null
+++ b/ldns/include/ldns/buffer.h
@@ -0,0 +1,645 @@
+/*
+ * buffer.h -- generic memory buffer.
+ *
+ * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ *
+ * The buffer module implements a generic buffer.  The API is based on
+ * the java.nio.Buffer interface.
+ */
+
+#ifndef LDNS_BUFFER_H
+#define LDNS_BUFFER_H
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <ldns/error.h>
+#include <ldns/common.h>
+
+#include "ldns/util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * number of initial bytes in buffer of
+ * which we cannot tell the size before hand
+ */
+#define LDNS_MIN_BUFLEN	512
+
+/**
+ * \file buffer.h
+ *
+ * This file contains the definition of ldns_buffer, and functions to manipulate those.
+ */
+
+/** 
+ * implementation of buffers to ease operations
+ *
+ * ldns_buffers can contain arbitrary information, per octet. You can write
+ * to the current end of a buffer, read from the current position, and
+ * access any data within it.
+ *
+ * Example use of buffers is in the source code of \ref host2str.c
+ */
+struct ldns_struct_buffer
+{
+	/** The current position used for reading/writing */ 
+	size_t   _position;
+
+	/** The read/write limit */
+	size_t   _limit;
+
+	/** The amount of data the buffer can contain */
+	size_t   _capacity;
+
+	/** The data contained in the buffer */
+	uint8_t *_data;
+
+	/** If the buffer is fixed it cannot be resized */
+	unsigned _fixed : 1;
+
+	/** The current state of the buffer. If writing to the buffer fails
+	 * for any reason, this value is changed. This way, you can perform
+	 * multiple writes in sequence and check for success afterwards. */
+	ldns_status _status;
+};
+typedef struct ldns_struct_buffer ldns_buffer;
+
+
+#ifdef NDEBUG
+INLINE void
+ldns_buffer_invariant(ldns_buffer *ATTR_UNUSED(buffer))
+{
+}
+#else
+INLINE void
+ldns_buffer_invariant(ldns_buffer *buffer)
+{
+	assert(buffer != NULL);
+	assert(buffer->_position <= buffer->_limit);
+	assert(buffer->_limit <= buffer->_capacity);
+	assert(buffer->_data != NULL);
+}
+#endif
+
+/**
+ * creates a new buffer with the specified capacity.
+ *
+ * \param[in] capacity the size (in bytes) to allocate for the buffer
+ * \return the created buffer
+ */
+ldns_buffer *ldns_buffer_new(size_t capacity);
+
+/**
+ * creates a buffer with the specified data.  The data IS copied
+ * and MEMORY allocations are done.  The buffer is not fixed and can
+ * be resized using buffer_reserve().
+ *
+ * \param[in] buffer pointer to the buffer to put the data in
+ * \param[in] data the data to encapsulate in the buffer
+ * \param[in] size the size of the data
+ */
+void ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size);
+
+/**
+ * clears the buffer and make it ready for writing.  The buffer's limit
+ * is set to the capacity and the position is set to 0.
+ * \param[in] buffer the buffer to clear
+ */
+INLINE void ldns_buffer_clear(ldns_buffer *buffer)
+{
+	ldns_buffer_invariant(buffer);
+
+	/* reset status here? */
+
+	buffer->_position = 0;
+	buffer->_limit = buffer->_capacity;
+}
+
+/**
+ * makes the buffer ready for reading the data that has been written to
+ * the buffer.  The buffer's limit is set to the current position and
+ * the position is set to 0.
+ *
+ * \param[in] buffer the buffer to flip
+ * \return void
+ */
+INLINE void ldns_buffer_flip(ldns_buffer *buffer)
+{
+	ldns_buffer_invariant(buffer);
+
+	buffer->_limit = buffer->_position;
+	buffer->_position = 0;
+}
+
+/**
+ * make the buffer ready for re-reading the data.  The buffer's
+ * position is reset to 0.
+ * \param[in] buffer the buffer to rewind
+ */
+INLINE void ldns_buffer_rewind(ldns_buffer *buffer)
+{
+	ldns_buffer_invariant(buffer);
+
+	buffer->_position = 0;
+}
+
+/**
+ * returns the current position in the buffer (as a number of bytes)
+ * \param[in] buffer the buffer
+ * \return the current position
+ */
+INLINE size_t
+ldns_buffer_position(ldns_buffer *buffer)
+{
+	return buffer->_position;
+}
+
+/**
+ * sets the buffer's position to MARK.  The position must be less than
+ * or equal to the buffer's limit.
+ * \param[in] buffer the buffer
+ * \param[in] mark the mark to use
+ */
+INLINE void
+ldns_buffer_set_position(ldns_buffer *buffer, size_t mark)
+{
+	assert(mark <= buffer->_limit);
+	buffer->_position = mark;
+}
+
+/**
+ * changes the buffer's position by COUNT bytes.  The position must not
+ * be moved behind the buffer's limit or before the beginning of the
+ * buffer.
+ * \param[in] buffer the buffer
+ * \param[in] count the count to use
+ */
+INLINE void
+ldns_buffer_skip(ldns_buffer *buffer, ssize_t count)
+{
+	assert(buffer->_position + count <= buffer->_limit);
+	buffer->_position += count;
+}
+
+/**
+ * returns the maximum size of the buffer
+ * \param[in] buffer
+ * \return the size
+ */
+INLINE size_t
+ldns_buffer_limit(ldns_buffer *buffer)
+{
+	return buffer->_limit;
+}
+
+/**
+ * changes the buffer's limit.  If the buffer's position is greater
+ * than the new limit the position is set to the limit.
+ * \param[in] buffer the buffer
+ * \param[in] limit the new limit
+ */
+INLINE void
+ldns_buffer_set_limit(ldns_buffer *buffer, size_t limit)
+{
+	assert(limit <= buffer->_capacity);
+	buffer->_limit = limit;
+	if (buffer->_position > buffer->_limit)
+		buffer->_position = buffer->_limit;
+}
+
+/**
+ * returns the number of bytes the buffer can hold.
+ * \param[in] buffer the buffer
+ * \return the number of bytes
+ */
+INLINE size_t
+ldns_buffer_capacity(ldns_buffer *buffer)
+{
+	return buffer->_capacity;
+}
+
+/**
+ * changes the buffer's capacity.  The data is reallocated so any
+ * pointers to the data may become invalid.  The buffer's limit is set
+ * to the buffer's new capacity.
+ * \param[in] buffer the buffer
+ * \param[in] capacity the capacity to use
+ * \return whether this failed or succeeded
+ */
+bool ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity);
+
+/**
+ * ensures BUFFER can contain at least AMOUNT more bytes.  The buffer's
+ * capacity is increased if necessary using buffer_set_capacity().
+ *
+ * The buffer's limit is always set to the (possibly increased)
+ * capacity.
+ * \param[in] buffer the buffer
+ * \param[in] amount amount to use
+ * \return whether this failed or succeeded
+ */
+bool ldns_buffer_reserve(ldns_buffer *buffer, size_t amount);
+
+/**
+ * returns a pointer to the data at the indicated position.
+ * \param[in] buffer the buffer
+ * \param[in] at position
+ * \return the pointer to the data
+ */
+INLINE uint8_t *
+ldns_buffer_at(const ldns_buffer *buffer, size_t at)
+{
+	assert(at <= buffer->_limit);
+	return buffer->_data + at;
+}
+
+/**
+ * returns a pointer to the beginning of the buffer (the data at
+ * position 0).
+ * \param[in] buffer the buffer
+ * \return the pointer
+ */
+INLINE uint8_t *
+ldns_buffer_begin(const ldns_buffer *buffer)
+{
+	return ldns_buffer_at(buffer, 0);
+}
+
+/**
+ * returns a pointer to the end of the buffer (the data at the buffer's
+ * limit).
+ * \param[in] buffer the buffer
+ * \return the pointer
+ */
+INLINE uint8_t *
+ldns_buffer_end(ldns_buffer *buffer)
+{
+	return ldns_buffer_at(buffer, buffer->_limit);
+}
+
+/**
+ * returns a pointer to the data at the buffer's current position.
+ * \param[in] buffer the buffer
+ * \return the pointer
+ */
+INLINE uint8_t *
+ldns_buffer_current(ldns_buffer *buffer)
+{
+	return ldns_buffer_at(buffer, buffer->_position);
+}
+
+/**
+ * returns the number of bytes remaining between the indicated position and
+ * the limit.
+ * \param[in] buffer the buffer
+ * \param[in] at indicated position
+ * \return number of bytes
+ */
+INLINE size_t
+ldns_buffer_remaining_at(ldns_buffer *buffer, size_t at)
+{
+	ldns_buffer_invariant(buffer);
+	assert(at <= buffer->_limit);
+	return buffer->_limit - at;
+}
+
+/**
+ * returns the number of bytes remaining between the buffer's position and
+ * limit.
+ * \param[in] buffer the buffer
+ * \return the number of bytes
+ */
+INLINE size_t
+ldns_buffer_remaining(ldns_buffer *buffer)
+{
+	return ldns_buffer_remaining_at(buffer, buffer->_position);
+}
+
+/**
+ * checks if the buffer has at least COUNT more bytes available.
+ * Before reading or writing the caller needs to ensure enough space
+ * is available!
+ * \param[in] buffer the buffer
+ * \param[in] at indicated position
+ * \param[in] count how much is available
+ * \return true or false (as int?)
+ */
+INLINE int
+ldns_buffer_available_at(ldns_buffer *buffer, size_t at, size_t count)
+{
+	return count <= ldns_buffer_remaining_at(buffer, at);
+}
+
+/**
+ * checks if the buffer has count bytes available at the current position
+ * \param[in] buffer the buffer
+ * \param[in] count how much is available
+ * \return true or false (as int?)
+ */
+INLINE int
+ldns_buffer_available(ldns_buffer *buffer, size_t count)
+{
+	return ldns_buffer_available_at(buffer, buffer->_position, count);
+}
+
+/**
+ * writes the given data to the buffer at the specified position
+ * \param[in] buffer the buffer
+ * \param[in] at the position (in number of bytes) to write the data at
+ * \param[in] data pointer to the data to write to the buffer
+ * \param[in] count the number of bytes of data to write
+ */
+INLINE void
+ldns_buffer_write_at(ldns_buffer *buffer, size_t at, const void *data, size_t count)
+{
+	assert(ldns_buffer_available_at(buffer, at, count));
+	memcpy(buffer->_data + at, data, count);
+}
+
+/**
+ * writes count bytes of data to the current position of the buffer
+ * \param[in] buffer the buffer
+ * \param[in] data the data to write
+ * \param[in] count the lenght of the data to write
+ */
+INLINE void
+ldns_buffer_write(ldns_buffer *buffer, const void *data, size_t count)
+{
+	ldns_buffer_write_at(buffer, buffer->_position, data, count);
+	buffer->_position += count;
+}
+
+/**
+ * copies the given (null-delimited) string to the specified position at the buffer
+ * \param[in] buffer the buffer
+ * \param[in] at the position in the buffer
+ * \param[in] str the string to write
+ */
+INLINE void
+ldns_buffer_write_string_at(ldns_buffer *buffer, size_t at, const char *str)
+{
+	ldns_buffer_write_at(buffer, at, str, strlen(str));
+}
+
+/**
+ * copies the given (null-delimited) string to the current position at the buffer
+ * \param[in] buffer the buffer
+ * \param[in] str the string to write
+ */
+INLINE void
+ldns_buffer_write_string(ldns_buffer *buffer, const char *str)
+{
+	ldns_buffer_write(buffer, str, strlen(str));
+}
+
+/**
+ * writes the given byte of data at the given position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] at the position in the buffer
+ * \param[in] data the 8 bits to write
+ */
+INLINE void
+ldns_buffer_write_u8_at(ldns_buffer *buffer, size_t at, uint8_t data)
+{
+	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
+	buffer->_data[at] = data;
+}
+
+/**
+ * writes the given byte of data at the current position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] data the 8 bits to write
+ */
+INLINE void
+ldns_buffer_write_u8(ldns_buffer *buffer, uint8_t data)
+{
+	ldns_buffer_write_u8_at(buffer, buffer->_position, data);
+	buffer->_position += sizeof(data);
+}
+
+/**
+ * writes the given 2 byte integer at the given position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] at the position in the buffer
+ * \param[in] data the 16 bits to write
+ */
+INLINE void
+ldns_buffer_write_u16_at(ldns_buffer *buffer, size_t at, uint16_t data)
+{
+	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
+	ldns_write_uint16(buffer->_data + at, data);
+}
+
+/**
+ * writes the given 2 byte integer at the current position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] data the 16 bits to write
+ */
+INLINE void
+ldns_buffer_write_u16(ldns_buffer *buffer, uint16_t data)
+{
+	ldns_buffer_write_u16_at(buffer, buffer->_position, data);
+	buffer->_position += sizeof(data);
+}
+
+/**
+ * writes the given 4 byte integer at the given position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] at the position in the buffer
+ * \param[in] data the 32 bits to write
+ */
+INLINE void
+ldns_buffer_write_u32_at(ldns_buffer *buffer, size_t at, uint32_t data)
+{
+	assert(ldns_buffer_available_at(buffer, at, sizeof(data)));
+	ldns_write_uint32(buffer->_data + at, data);
+}
+
+/**
+ * writes the given 4 byte integer at the current position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] data the 32 bits to write
+ */
+INLINE void
+ldns_buffer_write_u32(ldns_buffer *buffer, uint32_t data)
+{
+	ldns_buffer_write_u32_at(buffer, buffer->_position, data);
+	buffer->_position += sizeof(data);
+}
+
+/**
+ * copies count bytes of data at the given position to the given data-array
+ * \param[in] buffer the buffer
+ * \param[in] at the position in the buffer to start
+ * \param[out] data buffer to copy to
+ * \param[in] count the length of the data to copy
+ */
+INLINE void
+ldns_buffer_read_at(ldns_buffer *buffer, size_t at, void *data, size_t count)
+{
+	assert(ldns_buffer_available_at(buffer, at, count));
+	memcpy(data, buffer->_data + at, count);
+}
+
+/**
+ * copies count bytes of data at the current position to the given data-array
+ * \param[in] buffer the buffer
+ * \param[out] data buffer to copy to
+ * \param[in] count the length of the data to copy
+ */
+INLINE void
+ldns_buffer_read(ldns_buffer *buffer, void *data, size_t count)
+{
+	ldns_buffer_read_at(buffer, buffer->_position, data, count);
+	buffer->_position += count;
+}
+
+/**
+ * returns the byte value at the given position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] at the position in the buffer
+ * \return 1 byte integer
+ */
+INLINE uint8_t
+ldns_buffer_read_u8_at(ldns_buffer *buffer, size_t at)
+{
+	assert(ldns_buffer_available_at(buffer, at, sizeof(uint8_t)));
+	return buffer->_data[at];
+}
+
+/**
+ * returns the byte value at the current position in the buffer
+ * \param[in] buffer the buffer
+ * \return 1 byte integer
+ */
+INLINE uint8_t
+ldns_buffer_read_u8(ldns_buffer *buffer)
+{
+	uint8_t result = ldns_buffer_read_u8_at(buffer, buffer->_position);
+	buffer->_position += sizeof(uint8_t);
+	return result;
+}
+
+/**
+ * returns the 2-byte integer value at the given position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] at position in the buffer
+ * \return 2 byte integer
+ */
+INLINE uint16_t
+ldns_buffer_read_u16_at(ldns_buffer *buffer, size_t at)
+{
+	assert(ldns_buffer_available_at(buffer, at, sizeof(uint16_t)));
+	return ldns_read_uint16(buffer->_data + at);
+}
+
+/**
+ * returns the 2-byte integer value at the current position in the buffer
+ * \param[in] buffer the buffer
+ * \return 2 byte integer
+ */
+INLINE uint16_t
+ldns_buffer_read_u16(ldns_buffer *buffer)
+{
+	uint16_t result = ldns_buffer_read_u16_at(buffer, buffer->_position);
+	buffer->_position += sizeof(uint16_t);
+	return result;
+}
+
+/**
+ * returns the 4-byte integer value at the given position in the buffer
+ * \param[in] buffer the buffer
+ * \param[in] at position in the buffer
+ * \return 4 byte integer
+ */
+INLINE uint32_t
+ldns_buffer_read_u32_at(ldns_buffer *buffer, size_t at)
+{
+	assert(ldns_buffer_available_at(buffer, at, sizeof(uint32_t)));
+	return ldns_read_uint32(buffer->_data + at);
+}
+
+/**
+ * returns the 4-byte integer value at the current position in the buffer
+ * \param[in] buffer the buffer
+ * \return 4 byte integer
+ */
+INLINE uint32_t
+ldns_buffer_read_u32(ldns_buffer *buffer)
+{
+	uint32_t result = ldns_buffer_read_u32_at(buffer, buffer->_position);
+	buffer->_position += sizeof(uint32_t);
+	return result;
+}
+
+/**
+ * returns the status of the buffer
+ * \param[in] buffer
+ * \return the status
+ */
+INLINE ldns_status
+ldns_buffer_status(ldns_buffer *buffer)
+{
+	return buffer->_status;
+}
+
+/**
+ * returns true if the status of the buffer is LDNS_STATUS_OK, false otherwise
+ * \param[in] buffer the buffer
+ * \return true or false
+ */
+INLINE bool
+ldns_buffer_status_ok(ldns_buffer *buffer)
+{
+	if (buffer) {
+		return ldns_buffer_status(buffer) == LDNS_STATUS_OK;
+	} else {
+		return false;
+	}
+}
+
+/**
+ * prints to the buffer, increasing the capacity if required using
+ * buffer_reserve(). The buffer's position is set to the terminating '\\0'
+ * Returns the number of characters written (not including the
+ * terminating '\\0') or -1 on failure.
+ */
+int ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...);
+/*	ATTR_FORMAT(printf, 2, 3);*/
+
+/**
+ * frees the buffer.
+ * \param[in] *buffer the buffer to be freed
+ * \return void
+ */
+void ldns_buffer_free(ldns_buffer *buffer);
+
+/**
+ * Makes the buffer fixed and returns a pointer to the data.  The
+ * caller is responsible for free'ing the result.
+ * \param[in] *buffer the buffer to be exported
+ * \return void
+ */
+void *ldns_buffer_export(ldns_buffer *buffer);
+
+/**
+ * Copy contents of the from buffer to the result buffer and then flips 
+ * the result buffer. Data will be silently truncated if the result buffer is
+ * too small.
+ * \param[out] *result resulting buffer which is copied to.
+ * \param[in] *from what to copy to result.
+ */
+void ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_BUFFER_H */
diff --git a/ldns/include/ldns/common.h b/ldns/include/ldns/common.h
new file mode 100644
index 0000000..9abd9b9
--- /dev/null
+++ b/ldns/include/ldns/common.h
@@ -0,0 +1,78 @@
+/**
+ * \file common.h
+ *
+ * Common definitions for LDNS
+ */
+
+/**
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#ifndef LDNS_COMMON_H
+#define LDNS_COMMON_H
+
+/*
+ * The build configuration that is used in the distributed headers,
+ * as detected and determined by the auto configure script.
+ */
+#define LDNS_BUILD_CONFIG_HAVE_SSL         1
+#define LDNS_BUILD_CONFIG_HAVE_INTTYPES_H  1
+#define LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT 1
+#define LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED 1
+#define LDNS_BUILD_CONFIG_HAVE_SOCKLEN_T   1
+#define LDNS_BUILD_CONFIG_USE_DANE         1
+#define LDNS_BUILD_CONFIG_HAVE_B32_PTON    0
+#define LDNS_BUILD_CONFIG_HAVE_B32_NTOP    0
+
+/*
+ * HAVE_STDBOOL_H is not available when distributed as a library, but no build 
+ * configuration variables may be used (like those above) because the header
+ * is sometimes only available when using special compiler flags to enable the
+ * c99 environment. Because we cannot force the usage of this flag, we have to
+ * provide a default type. Below what is suggested by the autoconf manual.
+ */
+/*@ignore@*/
+/* splint barfs on this construct */
+#ifndef __bool_true_false_are_defined
+# ifdef HAVE_STDBOOL_H
+#  include <stdbool.h>
+# else
+#  ifndef HAVE__BOOL
+#   ifdef __cplusplus
+typedef bool _Bool;
+#   else
+#    define _Bool signed char
+#   endif
+#  endif
+#  define bool _Bool
+#  define false 0
+#  define true 1
+#  define __bool_true_false_are_defined 1
+# endif
+#endif
+/*@end@*/
+
+#if LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT
+#define ATTR_FORMAT(archetype, string_index, first_to_check) \
+    __attribute__ ((format (archetype, string_index, first_to_check)))
+#else /* !LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT */
+#define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
+#endif /* !LDNS_BUILD_CONFIG_HAVE_ATTR_FORMAT */
+
+#if defined(__cplusplus)
+#define ATTR_UNUSED(x)
+#elif LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED
+#define ATTR_UNUSED(x)  x __attribute__((unused))
+#else /* !LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED */
+#define ATTR_UNUSED(x)  x
+#endif /* !LDNS_BUILD_CONFIG_HAVE_ATTR_UNUSED */
+
+#if !LDNS_BUILD_CONFIG_HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
+#endif /* LDNS_COMMON_H */
diff --git a/ldns/include/ldns/config.h b/ldns/include/ldns/config.h
new file mode 100644
index 0000000..d77cc7f
--- /dev/null
+++ b/ldns/include/ldns/config.h
@@ -0,0 +1,590 @@
+#include "EXTERN.h"
+#include "perl.h"
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Whether the C compiler accepts the "format" attribute */
+#define HAVE_ATTR_FORMAT 1
+
+/* Whether the C compiler accepts the "unused" attribute */
+#define HAVE_ATTR_UNUSED 1
+
+/* Define to 1 if you have the `b32_ntop' function. */
+/* #undef HAVE_B32_NTOP */
+
+/* Define to 1 if you have the `b32_pton' function. */
+/* #undef HAVE_B32_PTON */
+
+/* Define to 1 if you have the `b64_ntop' function. */
+/* #undef HAVE_B64_NTOP */
+
+/* Define to 1 if you have the `b64_pton' function. */
+/* #undef HAVE_B64_PTON */
+
+/* Define to 1 if you have the `bzero' function. */
+#define HAVE_BZERO 1
+
+/* Define to 1 if you have the `calloc' function. */
+#define HAVE_CALLOC 1
+
+/* Define to 1 if you have the `ctime_r' function. */
+#define HAVE_CTIME_R 1
+
+/* Is a CAFILE given at configure time */
+#define HAVE_DANE_CA_FILE 0
+
+/* Is a CAPATH given at configure time */
+#define HAVE_DANE_CA_PATH 0
+
+/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
+   don't. */
+#define HAVE_DECL_NID_SECP384R1 1
+
+/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0
+   if you don't. */
+#define HAVE_DECL_NID_X9_62_PRIME256V1 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `endprotoent' function. */
+#define HAVE_ENDPROTOENT 1
+
+/* Define to 1 if you have the `endservent' function. */
+#define HAVE_ENDSERVENT 1
+
+/* Define to 1 if you have the `ENGINE_load_cryptodev' function. */
+#define HAVE_ENGINE_LOAD_CRYPTODEV 1
+
+/* Define to 1 if you have the `EVP_sha256' function. */
+#define HAVE_EVP_SHA256 1
+
+/* Define to 1 if you have the `fcntl' function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Whether getaddrinfo is available */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* If you have HMAC_CTX_init */
+#define HAVE_HMAC_CTX_INIT 1
+
+/* Define to 1 if you have the `inet_aton' function. */
+#define HAVE_INET_ATON 1
+
+/* Define to 1 if you have the `inet_ntop' function. */
+#define HAVE_INET_NTOP 1
+
+/* Define to 1 if you have the `inet_pton' function. */
+#define HAVE_INET_PTON 1
+
+/* define if you have inttypes.h */
+#define HAVE_INTTYPES_H 1
+
+/* if the function 'ioctlsocket' is available */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the `isascii' function. */
+#define HAVE_ISASCII 1
+
+/* Define to 1 if you have the `isblank' function. */
+#define HAVE_ISBLANK 1
+
+/* Define to 1 if you have the `pcap' library (-lpcap). */
+/* #undef HAVE_LIBPCAP */
+
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#define HAVE_MALLOC 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/if_ether.h> header file. */
+/* #undef HAVE_NETINET_IF_ETHER_H */
+
+/* Define to 1 if you have the <netinet/igmp.h> header file. */
+/* #undef HAVE_NETINET_IGMP_H */
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/in_systm.h> header file. */
+/* #undef HAVE_NETINET_IN_SYSTM_H */
+
+/* Define to 1 if you have the <netinet/ip6.h> header file. */
+/* #undef HAVE_NETINET_IP6_H */
+
+/* Define to 1 if you have the <netinet/ip_compat.h> header file. */
+/* #undef HAVE_NETINET_IP_COMPAT_H */
+
+/* Define to 1 if you have the <netinet/ip.h> header file. */
+/* #undef HAVE_NETINET_IP_H */
+
+/* Define to 1 if you have the <netinet/udp.h> header file. */
+/* #undef HAVE_NETINET_UDP_H */
+
+/* Define to 1 if you have the <net/ethernet.h> header file. */
+/* #undef HAVE_NET_ETHERNET_H */
+
+/* Define to 1 if you have the <net/if.h> header file. */
+/* #undef HAVE_NET_IF_H */
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the <openssl/rand.h> header file. */
+#define HAVE_OPENSSL_RAND_H 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <pcap.h> header file. */
+/* #undef HAVE_PCAP_H */
+
+/* Define to 1 if you have the `random' function. */
+#define HAVE_RANDOM 1
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+   and to 0 otherwise. */
+#define HAVE_REALLOC 1
+
+/* Define to 1 if you have the `sleep' function. */
+#define HAVE_SLEEP 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define if you have the SSL libraries installed. */
+#define HAVE_SSL /**/
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#ifdef HAS_STRLCPY
+#define HAVE_STRLCPY 1
+#else
+#undef HAVE_STRLCPY
+#endif
+
+/* Define to 1 if you have the `strtoul' function. */
+#define HAVE_STRTOUL 1
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#define HAVE_SYS_MOUNT_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* define if you have sys/socket.h */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* define if you have sys/types.h */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the `timegm' function. */
+#define HAVE_TIMEGM 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* define if you have unistd.h */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `vfork' function. */
+#define HAVE_VFORK 1
+
+/* Define to 1 if you have the <vfork.h> header file. */
+/* #undef HAVE_VFORK_H */
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if `fork' works. */
+#define HAVE_WORKING_FORK 1
+
+/* Define to 1 if `vfork' works. */
+#define HAVE_WORKING_VFORK 1
+
+/* Define to 1 if you have the <ws2tcpip.h> header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if the system has the type `_Bool'. */
+#define HAVE__BOOL 1
+
+/* Is a CAFILE given at configure time */
+/* #undef LDNS_DANE_CA_FILE */
+
+/* Is a CAPATH given at configure time */
+/* #undef LDNS_DANE_CA_PATH */
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "libdns@nlnetlabs.nl"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "ldns"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "ldns 1.6.17"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libdns"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.6.17"
+
+/* Define this to enable RR type NINFO. */
+/* #undef RRTYPE_NINFO */
+
+/* Define this to enable RR type OPENPGPKEY. */
+/* #undef RRTYPE_OPENPGPKEY */
+
+/* Define this to enable RR type RKEY. */
+/* #undef RRTYPE_RKEY */
+
+/* Define this to enable RR type TA. */
+/* #undef RRTYPE_TA */
+
+/* Define this to enable RR type URI. */
+/* #undef RRTYPE_URI */
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 8
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define this to enable messages to stderr. */
+/* #undef STDERR_MSGS */
+
+/* System configuration dir */
+#define SYSCONFDIR sysconfdir
+
+/* Define this to enable DANE support. */
+#define USE_DANE 1
+
+/* Define this to enable ECDSA support. */
+#define USE_ECDSA 1
+
+/* Define this to enable GOST support. */
+/* #define USE_GOST 1 */
+
+/* Define this to enable SHA256 and SHA512 support. */
+#define USE_SHA2 1
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+
+/* Whether the windows socket API is used */
+/* #undef USE_WINSOCK */
+
+/* the version of the windows API enabled */
+#define WINVER 0x0502
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Enable for compile on Minix */
+/* #undef _NETBSD_SOURCE */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* in_addr_t */
+/* #undef in_addr_t */
+
+/* in_port_t */
+/* #undef in_port_t */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `short' if <sys/types.h> does not define. */
+/* #undef int16_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef int32_t */
+
+/* Define to `long long' if <sys/types.h> does not define. */
+/* #undef int64_t */
+
+/* Define to `char' if <sys/types.h> does not define. */
+/* #undef int8_t */
+
+/* Define to `size_t' if <sys/types.h> does not define. */
+/* #undef intptr_t */
+
+/* Define to rpl_malloc if the replacement function should be used. */
+/* #undef malloc */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to rpl_realloc if the replacement function should be used. */
+/* #undef realloc */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define to 'int' if not defined */
+/* #undef socklen_t */
+
+/* Fallback member name for socket family in struct sockaddr_storage */
+/* #undef ss_family */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef ssize_t */
+
+/* Define to `unsigned short' if <sys/types.h> does not define. */
+/* #undef uint16_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef uint32_t */
+
+/* Define to `unsigned long long' if <sys/types.h> does not define. */
+/* #undef uint64_t */
+
+/* Define to `unsigned char' if <sys/types.h> does not define. */
+/* #undef uint8_t */
+
+/* Define as `fork' if `vfork' does not work. */
+/* #undef vfork */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN 4321
+#endif
+
+#ifndef BYTE_ORDER
+#ifdef WORDS_BIGENDIAN
+#define BYTE_ORDER BIG_ENDIAN
+#else
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif /* WORDS_BIGENDIAN */
+#endif /* BYTE_ORDER */
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+
+
+/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
+#ifdef HAVE_WINSOCK2_H
+#define FD_SET_T (u_int)
+#else
+#define FD_SET_T 
+#endif
+
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ldns_b64_ntop(uint8_t const *src, size_t srclength,
+	 	  char *target, size_t targsize);
+/**
+ * calculates the size needed to store the result of b64_ntop
+ */
+/*@unused@*/
+static inline size_t ldns_b64_ntop_calculate_size(size_t srcsize)
+{
+	return ((((srcsize + 2) / 3) * 4) + 1);
+}
+int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
+/**
+ * calculates the size needed to store the result of ldns_b64_pton
+ */
+/*@unused@*/
+static inline size_t ldns_b64_pton_calculate_size(size_t srcsize)
+{
+	return (((((srcsize + 3) / 4) * 3)) + 1);
+}
+
+/**
+ * Given in dnssec_zone.c, also used in dnssec_sign.c:w
+
+ */
+int ldns_dname_compare_v(const void *a, const void *b);
+
+#ifndef HAVE_SLEEP
+/* use windows sleep, in millisecs, instead */
+#define sleep(x) Sleep((x)*1000)
+#endif
+
+#ifndef HAVE_RANDOM
+#define srandom(x) srand(x)
+#define random(x) rand(x)
+#endif
+
+#ifndef HAVE_TIMEGM
+#include <time.h>
+time_t timegm (struct tm *tm);
+#endif /* !TIMEGM */
+#ifndef HAVE_GMTIME_R
+struct tm *gmtime_r(const time_t *timep, struct tm *result);
+#endif
+#ifndef HAVE_LOCALTIME_R
+struct tm *localtime_r(const time_t *timep, struct tm *result);
+#endif
+#ifndef HAVE_ISBLANK
+int isblank(int c);
+#endif /* !HAVE_ISBLANK */
+#ifndef HAVE_ISASCII
+int isascii(int c);
+#endif /* !HAVE_ISASCII */
+#ifndef HAVE_SNPRINTF
+#include <stdarg.h>
+int snprintf (char *str, size_t count, const char *fmt, ...);
+int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
+#endif /* HAVE_SNPRINTF */
+#ifndef HAVE_INET_PTON
+int inet_pton(int af, const char* src, void* dst);
+#endif /* HAVE_INET_PTON */
+#ifndef HAVE_INET_NTOP
+const char *inet_ntop(int af, const void *src, char *dst, size_t size);
+#endif
+#ifndef HAVE_INET_ATON
+int inet_aton(const char *cp, struct in_addr *addr);
+#endif
+#ifndef HAVE_MEMMOVE
+void *memmove(void *dest, const void *src, size_t n);
+#endif
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *dst, const char *src, size_t siz);
+#endif
+#ifdef __cplusplus
+}
+#endif
+#ifndef HAVE_GETADDRINFO
+#include "compat/fake-rfc2553.h"
+#endif
+#ifndef HAVE_STRTOUL
+#define strtoul (unsigned long)strtol
+#endif
+
diff --git a/ldns/include/ldns/dane.h b/ldns/include/ldns/dane.h
new file mode 100644
index 0000000..8234eb7
--- /dev/null
+++ b/ldns/include/ldns/dane.h
@@ -0,0 +1,262 @@
+/*
+ * dane.h -- defines for the DNS-Based Authentication of Named Entities (DANE)
+ *                           Transport Layer Security (TLS) Protocol: TLSA
+ *
+ * Copyright (c) 2012, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ */
+
+/**
+ * \file
+ *
+ * This module contains base functions for creating and verifying TLSA RR's
+ * with PKIX certificates, certificate chains and validation stores.
+ * (See RFC6394 and RFC6698).
+ * 
+ * Since those functions heavily rely op cryptographic operations,
+ * this module is dependent on openssl.
+ */
+ 
+
+#ifndef LDNS_DANE_H
+#define LDNS_DANE_H
+#if LDNS_BUILD_CONFIG_USE_DANE
+
+#include <ldns/common.h>
+#include <ldns/rdata.h>
+#include <ldns/rr.h>
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The different "Certificate usage" rdata field values for a TLSA RR.
+ */
+enum ldns_enum_tlsa_certificate_usage
+{
+	/** CA constraint */
+	LDNS_TLSA_USAGE_PKIX_TA				=   0,
+	LDNS_TLSA_USAGE_CA_CONSTRAINT			=   0,
+	/** Sevice certificate constraint */
+	LDNS_TLSA_USAGE_PKIX_EE				=   1,
+	LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT	=   1,
+	/** Trust anchor assertion */
+	LDNS_TLSA_USAGE_DANE_TA				=   2,
+	LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION		=   2,
+	/** Domain issued certificate */
+	LDNS_TLSA_USAGE_DANE_EE				=   3,
+	LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE	=   3,
+	/** Reserved for Private Use */
+	LDNS_TLSA_USAGE_PRIVCERT			= 255
+};
+typedef enum ldns_enum_tlsa_certificate_usage ldns_tlsa_certificate_usage;
+
+/**
+ * The different "Selector" rdata field values for a TLSA RR.
+ */
+enum ldns_enum_tlsa_selector
+{
+	/** 
+	 * Full certificate: the Certificate binary structure
+	 * as defined in [RFC5280]
+	 */
+	LDNS_TLSA_SELECTOR_CERT			=   0,
+	LDNS_TLSA_SELECTOR_FULL_CERTIFICATE	=   0,
+
+	/** 
+	 * SubjectPublicKeyInfo: DER-encoded binary structure
+	 * as defined in [RFC5280]
+	 */
+	LDNS_TLSA_SELECTOR_SPKI			=   1,
+	LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO	=   1,
+
+	/** Reserved for Private Use */
+	LDNS_TLSA_SELECTOR_PRIVSEL		= 255
+};
+typedef enum ldns_enum_tlsa_selector ldns_tlsa_selector;
+
+/**
+ * The different "Matching type" rdata field values for a TLSA RR.
+ */
+enum ldns_enum_tlsa_matching_type
+{
+	/** Exact match on selected content */
+	LDNS_TLSA_MATCHING_TYPE_FULL		=   0,
+	LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED	=   0,
+	/** SHA-256 hash of selected content [RFC6234] */
+	LDNS_TLSA_MATCHING_TYPE_SHA2_256	=   1,
+	LDNS_TLSA_MATCHING_TYPE_SHA256		=   1,
+	/** SHA-512 hash of selected content [RFC6234] */
+	LDNS_TLSA_MATCHING_TYPE_SHA2_512	=   2,
+	LDNS_TLSA_MATCHING_TYPE_SHA512		=   2,
+	/** Reserved for Private Use */
+	LDNS_TLSA_MATCHING_TYPE_PRIVMATCH	= 255
+};
+typedef enum ldns_enum_tlsa_matching_type ldns_tlsa_matching_type;
+
+/**
+ * Known transports to use with TLSA owner names.
+ */
+enum ldns_enum_dane_transport
+{
+	/** TCP */
+	LDNS_DANE_TRANSPORT_TCP  = 0,
+	/** UDP */
+	LDNS_DANE_TRANSPORT_UDP  = 1,
+	/** SCTP */
+	LDNS_DANE_TRANSPORT_SCTP = 2
+};
+typedef enum ldns_enum_dane_transport ldns_dane_transport;
+
+
+/**
+ * Creates a dname consisting of the given name, prefixed by the service port
+ * and type of transport: _<EM>port</EM>._<EM>transport</EM>.<EM>name</EM>.
+ *
+ * \param[out] tlsa_owner The created dname.
+ * \param[in] name The dname that should be prefixed.
+ * \param[in] port The service port number for wich the name should be created.
+ * \param[in] transport The transport for wich the name should be created.
+ * \return LDNS_STATUS_OK on success or an error code otherwise.
+ */
+ldns_status ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner,
+		const ldns_rdf* name, uint16_t port,
+		ldns_dane_transport transport);
+
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * Creates a LDNS_RDF_TYPE_HEX type rdf based on the binary data choosen by
+ * the selector and encoded using matching_type.
+ *
+ * \param[out] rdf The created created rdf of type LDNS_RDF_TYPE_HEX.
+ * \param[in] cert The certificate from which the data is selected
+ * \param[in] selector The full certificate or the public key
+ * \param[in] matching_type The full data or the SHA256 or SHA512 hash
+ *            of the selected data
+ * \return LDNS_STATUS_OK on success or an error code otherwise.
+ */
+ldns_status ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
+		ldns_tlsa_selector      selector,
+		ldns_tlsa_matching_type matching_type);
+
+
+/**
+ * Selects the certificate from cert, extra_certs or the pkix_validation_store
+ * based on the value of cert_usage and index.
+ *
+ * \param[out] selected_cert The selected cert.
+ * \param[in] cert The certificate to validate (or not)
+ * \param[in] extra_certs Intermediate certificates that might be necessary
+ *            during validation. May be NULL, except when the certificate 
+ *            usage is "Trust Anchor Assertion" because the trust anchor has
+ *            to be provided.(otherwise choose a "Domain issued certificate!"
+ * \param[in] pkix_validation_store Used when the certificate usage is 
+ *            "CA constraint" or "Service Certificate Constraint" to 
+ *            validate the certificate and, in case of "CA constraint",
+ *            select the CA.
+ *            When pkix_validation_store is NULL, validation is explicitely
+ *            turned off and the behaviour is then the same as for "Trust
+ *            anchor assertion" and "Domain issued certificate" respectively.
+ * \param[in] cert_usage Which certificate to use and how to validate.
+ * \param[in] index Used to select the trust anchor when certificate usage
+ *            is "Trust Anchor Assertion". 0 is the last certificate in the
+ *            validation chain. 1 the one but last, etc. When index is -1,
+ *            the last certificate is used that MUST be self-signed.
+ *            This can help to make sure that the intended (self signed)
+ *            trust anchor is actually present in extra_certs (which is a
+ *            DANE requirement).
+ *
+ * \return LDNS_STATUS_OK on success or an error code otherwise.
+ */
+ldns_status ldns_dane_select_certificate(X509** selected_cert,
+		X509* cert, STACK_OF(X509)* extra_certs,
+		X509_STORE* pkix_validation_store,
+		ldns_tlsa_certificate_usage cert_usage, int index);
+
+/**
+ * Creates a TLSA resource record from the certificate.
+ * No PKIX validation is performed! The given certificate is used as data
+ * regardless the value of certificate_usage.
+ *
+ * \param[out] tlsa The created TLSA resource record.
+ * \param[in] certificate_usage The value for the Certificate Usage field
+ * \param[in] selector The value for the Selector field
+ * \param[in] matching_type The value for the Matching Type field
+ * \param[in] cert The certificate which data will be represented
+ *
+ * \return LDNS_STATUS_OK on success or an error code otherwise.
+ */
+ldns_status ldns_dane_create_tlsa_rr(ldns_rr** tlsa,
+		ldns_tlsa_certificate_usage certificate_usage,
+		ldns_tlsa_selector          selector,
+		ldns_tlsa_matching_type     matching_type,
+		X509* cert);
+
+/**
+ * Verify if the given TLSA resource record matches the given certificate.
+ * Reporting on a TLSA rr mismatch (LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH)
+ * is preferred over PKIX failure  (LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE).
+ * So when PKIX validation is required by the TLSA Certificate usage,
+ * but the TLSA data does not match, LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH
+ * is returned whether the PKIX validated or not.
+ *
+ * \param[in] tlsa_rr The resource record that specifies what and how to
+ *            match the certificate. With tlsa_rr == NULL, regular PKIX
+ *            validation is performed.
+ * \param[in] cert The certificate to match (and validate)
+ * \param[in] extra_certs Intermediate certificates that might be necessary
+ *            creating the validation chain.
+ * \param[in] pkix_validation_store Used when the certificate usage is 
+ *            "CA constraint" or "Service Certificate Constraint" to 
+ *            validate the certificate.
+ *
+ * \return LDNS_STATUS_OK on success,
+ *         LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH on TLSA data mismatch,
+ *         LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE when TLSA matched,
+ *         but the PKIX validation failed, or other ldns_status errors.
+ */
+ldns_status ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
+		X509* cert, STACK_OF(X509)* extra_certs,
+		X509_STORE* pkix_validation_store);
+
+/**
+ * Verify if any of the given TLSA resource records matches the given
+ * certificate.
+ *
+ * \param[in] tlsas The resource records that specify what and how to
+ *            match the certificate. One must match for this function
+ *            to succeed. With tlsas == NULL or the number of TLSA records
+ *            in tlsas == 0, regular PKIX validation is performed.
+ * \param[in] cert The certificate to match (and validate)
+ * \param[in] extra_certs Intermediate certificates that might be necessary
+ *            creating the validation chain.
+ * \param[in] pkix_validation_store Used when the certificate usage is 
+ *            "CA constraint" or "Service Certificate Constraint" to 
+ *            validate the certificate.
+ *
+ * \return LDNS_STATUS_OK on success,
+ *         LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE when one of the TLSA's
+ *         matched but the PKIX validation failed,
+ *         LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH when none of the TLSA's matched,
+ *         or other ldns_status errors.
+ */
+ldns_status ldns_dane_verify(ldns_rr_list* tlsas,
+		X509* cert, STACK_OF(X509)* extra_certs,
+		X509_STORE* pkix_validation_store);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_BUILD_CONFIG_USE_DANE */
+#endif /* LDNS_DANE_H */
+
diff --git a/ldns/include/ldns/dname.h b/ldns/include/ldns/dname.h
new file mode 100644
index 0000000..291786b
--- /dev/null
+++ b/ldns/include/ldns/dname.h
@@ -0,0 +1,211 @@
+/*
+ * dname.h
+ *
+ * dname definitions
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file dname.h
+ *
+ * dname contains function to read and manipulate domain names.
+ *
+ * Example domain names are "www.nlnetlabs.nl." and "." (the root)
+ *
+ * If a domain name ends with a dot ("."), it is called a Fully Qualified
+ * Domain Name (FQDN). In certain places (for instance when reading a zone
+ * file), an origin (which is just another domain name) non-FQDNs will be
+ * placed after the current. For instance, if i have a zone file where the
+ * origin has been set to "nl.", and my file contains the name
+ * "www.nlnetlabs", it will result in "www.nlnetlabs.nl.". Internally, dnames are
+ * always absolute (the dot is added when it is missing and there is no origin).
+ *
+ * An FQDN is also
+ * known as an absolute domain name, therefore the function to check this is
+ * called \ref ldns_dname_str_absolute
+ *
+ * Domain names are stored in \ref ldns_rdf structures, with the type
+ * \ref LDNS_RDF_TYPE_DNAME
+ *
+ * This module is *NOT* about the RR type called DNAME.
+ */
+
+
+#ifndef LDNS_DNAME_H
+#define LDNS_DNAME_H
+
+#include <ldns/common.h>
+#include <ldns/rdata.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LDNS_DNAME_NORMALIZE        tolower
+
+/**
+ * concatenates two dnames together
+ * \param[in] rd1 the leftside
+ * \param[in] rd2 the rightside
+ * \return a new rdf with leftside/rightside
+ */
+ldns_rdf *ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2);
+
+/**
+ * concatenates rd2 after rd1 (rd2 is copied, rd1 is modified)
+ * \param[in] rd1 the leftside
+ * \param[in] rd2 the rightside
+ * \return LDNS_STATUS_OK on success
+ */
+ldns_status 	ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2);
+
+/**
+ * Returns a clone of the given dname with the labels
+ * reversed
+ * \param[in] d the dname to reverse
+ * \return clone of the dname with the labels reversed.
+ */
+ldns_rdf *ldns_dname_reverse(const ldns_rdf *d);
+
+/**
+ * Clones the given dname from the nth label on
+ * \param[in] d The dname to clone
+ * \param[in] n the label nr to clone from, if this is 0, the complete
+ *              dname is cloned
+ * \return A newly allocated *rdf structure, containing the cloned dname,
+ *         or NULL if either d was NULL, not a dname, or if n >=
+ *         label_count
+ */
+ldns_rdf *
+ldns_dname_clone_from(const ldns_rdf *d, uint16_t n);
+
+/**
+ * chop one label off the left side of a dname. so
+ * wwww.nlnetlabs.nl, becomes nlnetlabs.nl
+ * This new name is a clone and must be freed with ldns_deep_free()
+ * \param[in] d the dname to chop
+ * \return the remaining dname
+ */
+ldns_rdf *ldns_dname_left_chop(const ldns_rdf *d);
+
+/**
+ * count the number of labels inside a LDNS_RDF_DNAME type rdf.
+ * \param[in] *r the rdf
+ * \return the number of labels
+ */
+uint8_t  ldns_dname_label_count(const ldns_rdf *r);
+
+/**
+ * creates a new dname rdf from a string.
+ * \param[in] str string to use
+ * \return ldns_rdf* or NULL in case of an error
+ */
+ldns_rdf *ldns_dname_new_frm_str(const char *str);
+
+/**
+ * Create a new dname rdf from a string
+ * \param[in] s the size of the new dname
+ * \param[in] *data pointer to the actual data
+ *
+ * \return ldns_rdf*
+ */
+ldns_rdf *ldns_dname_new(uint16_t s, void *data);
+
+/**
+ * Create a new dname rdf from data (the data is copied)
+ * \param[in] size the size of the data
+ * \param[in] *data pointer to the actual data
+ *
+ * \return ldns_rdf*
+ */
+ldns_rdf *ldns_dname_new_frm_data(uint16_t size, const void *data);
+
+/**
+ * Put a dname into canonical fmt - ie. lowercase it
+ * \param[in] rdf the dname to lowercase
+ * \return void
+ */
+void ldns_dname2canonical(const ldns_rdf *rdf);
+
+/**
+ * test wether the name sub falls under parent (i.e. is a subdomain
+ * of parent). This function will return false if the given dnames are
+ * equal.
+ * \param[in] sub the name to test
+ * \param[in] parent the parent's name
+ * \return true if sub falls under parent, otherwise false
+ */
+bool ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent);
+
+/**
+ * Compares the two dname rdf's according to the algorithm for ordering
+ * in RFC4034 Section 6.
+ * \param[in] dname1 First dname rdf to compare
+ * \param[in] dname2 Second dname rdf to compare
+ * \return -1 if dname1 comes before dname2, 1 if dname1 comes after dname2, and 0 if they are equal.
+ */
+int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2);
+int ldns_dname_compare_v(const void *, const void *);
+
+/**
+ * Checks whether the dname matches the given wildcard
+ * \param[in] dname The dname to check
+ * \param[in] wildcard The wildcard to check with
+ * \return 1 If the wildcard matches, OR if 'wildcard' is not a wildcard and
+ *           the names are *exactly* the same
+ *         0 If the wildcard does not match, or if it is not a wildcard and
+ *           the names are not the same
+ */
+int ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard);
+
+/**
+ * check if middle lays in the interval defined by prev and next
+ * prev <= middle < next. This is usefull for nsec checking
+ * \param[in] prev the previous dname
+ * \param[in] middle the dname to check
+ * \param[in] next the next dname
+ * return 0 on error or unknown, -1 when middle is in the interval, +1 when not
+ */
+int ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle, const ldns_rdf *next);
+
+/**
+ * Checks whether the given dname string is absolute (i.e. ends with a '.')
+ * \param[in] *dname_str a string representing the dname
+ * \return true or false
+ */
+bool ldns_dname_str_absolute(const char *dname_str);
+
+/**
+ * Checks whether the given dname is absolute (i.e. ends with a '.')
+ * \param[in] *dname a rdf representing the dname
+ * \return true or false
+ */
+bool ldns_dname_absolute(const ldns_rdf *dname);
+
+/**
+ * look inside the rdf and if it is an LDNS_RDF_TYPE_DNAME
+ * try and retrieve a specific label. The labels are numbered
+ * starting from 0 (left most).
+ * \param[in] rdf the rdf to look in
+ * \param[in] labelpos return the label with this number
+ * \return a ldns_rdf* with the label as name or NULL on error
+ */
+ldns_rdf * ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos);
+
+/**
+ * Check if dname is a wildcard, starts with *.
+ * \param[in] dname: the rdf to look in
+ * \return true if a wildcard, false if not.
+ */
+int ldns_dname_is_wildcard(const ldns_rdf* dname);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* LDNS_DNAME_H */
diff --git a/ldns/include/ldns/dnssec.h b/ldns/include/ldns/dnssec.h
new file mode 100644
index 0000000..f4cdafb
--- /dev/null
+++ b/ldns/include/ldns/dnssec.h
@@ -0,0 +1,541 @@
+/*
+ * dnssec.h -- defines for the Domain Name System (SEC) (DNSSEC)
+ *
+ * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ * A bunch of defines that are used in the DNS
+ */
+
+/**
+ * \file dnssec.h
+ *
+ * This module contains base functions for DNSSEC operations
+ * (RFC4033 t/m RFC4035).
+ * 
+ * Since those functions heavily rely op cryptographic operations,
+ * this module is dependent on openssl.
+ * 
+ */
+ 
+
+#ifndef LDNS_DNSSEC_H
+#define LDNS_DNSSEC_H
+
+#include <ldns/common.h>
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+#include <ldns/packet.h>
+#include <ldns/keys.h>
+#include <ldns/zone.h>
+#include <ldns/resolver.h>
+#include <ldns/dnssec_zone.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LDNS_MAX_KEYLEN		2048
+#define LDNS_DNSSEC_KEYPROTO	3
+/* default time before sigs expire */
+#define LDNS_DEFAULT_EXP_TIME	2419200 /* 4 weeks */
+
+/** return values for the old-signature callback */
+#define LDNS_SIGNATURE_LEAVE_ADD_NEW 0
+#define LDNS_SIGNATURE_LEAVE_NO_ADD 1
+#define LDNS_SIGNATURE_REMOVE_ADD_NEW 2
+#define LDNS_SIGNATURE_REMOVE_NO_ADD 3
+
+/**
+ * Returns the first RRSIG rr that corresponds to the rrset 
+ * with the given name and type
+ * 
+ * \param[in] name The dname of the RRset covered by the RRSIG to find
+ * \param[in] type The type of the RRset covered by the RRSIG to find
+ * \param[in] rrs List of rrs to search in
+ * \returns Pointer to the first RRsig ldns_rr found, or NULL if it is
+ * not present
+ */
+ldns_rr *ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name,
+									    const ldns_rr_type type,
+									    const ldns_rr_list *rrs);
+
+/**
+ * Returns the DNSKEY that corresponds to the given RRSIG rr from the list, if
+ * any
+ *
+ * \param[in] rrsig The rrsig to find the DNSKEY for
+ * \param[in] rrs The rr list to find the key in
+ * \return The DNSKEY that corresponds to the given RRSIG, or NULL if it was
+ *         not found.
+ */
+ldns_rr *ldns_dnssec_get_dnskey_for_rrsig(const ldns_rr *rrsig, const ldns_rr_list *rrs);
+
+/**
+ * Returns the rdata field that contains the bitmap of the covered types of
+ * the given NSEC record
+ *
+ * \param[in] nsec The nsec to get the covered type bitmap of
+ * \return An ldns_rdf containing the bitmap, or NULL on error
+ */
+ldns_rdf *ldns_nsec_get_bitmap(ldns_rr *nsec);
+
+
+#define LDNS_NSEC3_MAX_ITERATIONS 65535
+
+/**
+ * Returns the dname of the closest (provable) encloser
+ */
+ldns_rdf *
+ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
+							ldns_rr_type qtype,
+							ldns_rr_list *nsec3s);
+
+/**
+ * Checks whether the packet contains rrsigs
+ */
+bool
+ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt);
+
+/**
+ * Returns a ldns_rr_list containing the signatures covering the given name
+ * and type
+ */
+ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type);
+
+/**
+ * Returns a ldns_rr_list containing the signatures covering the given type
+ */
+ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type);
+
+/** 
+ * calculates a keytag of a key for use in DNSSEC.
+ *
+ * \param[in] key the key as an RR to use for the calc.
+ * \return the keytag
+ */
+uint16_t ldns_calc_keytag(const ldns_rr *key);
+
+/**
+ * Calculates keytag of DNSSEC key, operates on wireformat rdata.
+ * \param[in] key the key as uncompressed wireformat rdata.
+ * \param[in] keysize length of key data.
+ * \return the keytag
+ */
+uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize);
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * converts a buffer holding key material to a DSA key in openssl.
+ *
+ * \param[in] key the key to convert
+ * \return a DSA * structure with the key material
+ */
+DSA *ldns_key_buf2dsa(ldns_buffer *key);
+/**
+ * Like ldns_key_buf2dsa, but uses raw buffer.
+ * \param[in] key the uncompressed wireformat of the key.
+ * \param[in] len length of key data
+ * \return a DSA * structure with the key material
+ */
+DSA *ldns_key_buf2dsa_raw(unsigned char* key, size_t len);
+
+/**
+ * Utility function to calculate hash using generic EVP_MD pointer.
+ * \param[in] data the data to hash.
+ * \param[in] len  length of data.
+ * \param[out] dest the destination of the hash, must be large enough.
+ * \param[in] md the message digest to use.
+ * \return true if worked, false on failure.
+ */
+int ldns_digest_evp(unsigned char* data, unsigned int len, 
+	unsigned char* dest, const EVP_MD* md);
+
+/**
+ * Converts a holding buffer with key material to EVP PKEY in openssl.
+ * Only available if ldns was compiled with GOST.
+ * \param[in] key data to convert
+ * \param[in] keylen length of the key data
+ * \return the key or NULL on error.
+ */
+EVP_PKEY* ldns_gost2pkey_raw(unsigned char* key, size_t keylen);
+
+/**
+ * Converts a holding buffer with key material to EVP PKEY in openssl.
+ * Only available if ldns was compiled with ECDSA.
+ * \param[in] key data to convert
+ * \param[in] keylen length of the key data
+ * \param[in] algo precise algorithm to initialize ECC group values.
+ * \return the key or NULL on error.
+ */
+EVP_PKEY* ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo);
+
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * converts a buffer holding key material to a RSA key in openssl.
+ *
+ * \param[in] key the key to convert
+ * \return a RSA * structure with the key material
+ */
+RSA *ldns_key_buf2rsa(ldns_buffer *key);
+
+/**
+ * Like ldns_key_buf2rsa, but uses raw buffer.
+ * \param[in] key the uncompressed wireformat of the key.
+ * \param[in] len length of key data
+ * \return a RSA * structure with the key material
+ */
+RSA *ldns_key_buf2rsa_raw(unsigned char* key, size_t len);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+/** 
+ * returns a new DS rr that represents the given key rr.
+ *
+ * \param[in] *key the key to convert
+ * \param[in] h the hash to use LDNS_SHA1/LDNS_SHA256
+ *
+ * \return ldns_rr* a new rr pointer to a DS
+ */
+ldns_rr *ldns_key_rr2ds(const ldns_rr *key, ldns_hash h);
+
+/**
+ * Create the type bitmap for an NSEC(3) record
+ */
+ldns_rdf *
+ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
+						 size_t size,
+						 ldns_rr_type nsec_type);
+
+/**
+ * returns whether a rrset of the given type is found in the rrsets.
+ *
+ * \param[in] rrsets the rrsets to be tested
+ * \param[in] type the type to test for
+ * \return int 1 if the type was found, 0 otherwise.
+ */
+int
+ldns_dnssec_rrsets_contains_type (ldns_dnssec_rrsets *rrsets, ldns_rr_type type);
+
+/**
+ * Creates NSEC
+ */
+ldns_rr *
+ldns_dnssec_create_nsec(ldns_dnssec_name *from,
+				    ldns_dnssec_name *to,
+				    ldns_rr_type nsec_type);
+
+
+/**
+ * Creates NSEC3
+ */
+ldns_rr *
+ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
+					ldns_dnssec_name *to,
+					ldns_rdf *zone_name,
+					uint8_t algorithm,
+					uint8_t flags,
+					uint16_t iterations,
+					uint8_t salt_length,
+					uint8_t *salt);
+
+/**
+ * Create a NSEC record
+ * \param[in] cur_owner the current owner which should be taken as the starting point
+ * \param[in] next_owner the rrlist which the nsec rr should point to 
+ * \param[in] rrs all rrs from the zone, to find all RR types of cur_owner in
+ * \return a ldns_rr with the nsec record in it
+ */
+ldns_rr * ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs);
+
+/**
+ * Calculates the hashed name using the given parameters
+ * \param[in] *name The owner name to calculate the hash for 
+ * \param[in] algorithm The hash algorithm to use
+ * \param[in] iterations The number of hash iterations to use
+ * \param[in] salt_length The length of the salt in bytes
+ * \param[in] salt The salt to use
+ * \return The hashed owner name rdf, without the domain name
+ */
+ldns_rdf *ldns_nsec3_hash_name(ldns_rdf *name, uint8_t algorithm, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
+
+/**
+ * Sets all the NSEC3 options. The rr to set them in must be initialized with _new() and
+ * type LDNS_RR_TYPE_NSEC3
+ * \param[in] *rr The RR to set the values in
+ * \param[in] algorithm The NSEC3 hash algorithm 
+ * \param[in] flags The flags field 
+ * \param[in] iterations The number of hash iterations
+ * \param[in] salt_length The length of the salt in bytes 
+ * \param[in] salt The salt bytes
+ */
+void ldns_nsec3_add_param_rdfs(ldns_rr *rr,
+						 uint8_t algorithm,
+						 uint8_t flags,
+						 uint16_t iterations,
+						 uint8_t salt_length,
+						 uint8_t *salt);
+
+/* this will NOT return the NSEC3  completed, you will have to run the
+   finalize function on the rrlist later! */
+ldns_rr *
+ldns_create_nsec3(ldns_rdf *cur_owner,
+                  ldns_rdf *cur_zone,
+                  ldns_rr_list *rrs,
+                  uint8_t algorithm,
+                  uint8_t flags,
+                  uint16_t iterations,
+                  uint8_t salt_length,
+                  uint8_t *salt,
+                  bool emptynonterminal);
+
+/**
+ * Returns the hash algorithm used in the given NSEC3 RR
+ * \param[in] *nsec3_rr The RR to read from
+ * \return The algorithm identifier, or 0 on error
+ */
+uint8_t ldns_nsec3_algorithm(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns flags field
+ */
+uint8_t
+ldns_nsec3_flags(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns true if the opt-out flag has been set in the given NSEC3 RR
+ * \param[in] *nsec3_rr The RR to read from
+ * \return true if the RR has type NSEC3 and the opt-out bit has been set, false otherwise
+ */
+bool ldns_nsec3_optout(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns the number of hash iterations used in the given NSEC3 RR
+ * \param[in] *nsec3_rr The RR to read from
+ * \return The number of iterations
+ */
+uint16_t ldns_nsec3_iterations(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns the salt used in the given NSEC3 RR
+ * \param[in] *nsec3_rr The RR to read from
+ * \return The salt rdf, or NULL on error
+ */
+ldns_rdf *ldns_nsec3_salt(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns the length of the salt used in the given NSEC3 RR
+ * \param[in] *nsec3_rr The RR to read from
+ * \return The length of the salt in bytes
+ */
+uint8_t ldns_nsec3_salt_length(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns the salt bytes used in the given NSEC3 RR
+ * \param[in] *nsec3_rr The RR to read from
+ * \return The salt in bytes, this is alloced, so you need to free it
+ */
+uint8_t *ldns_nsec3_salt_data(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns the first label of the next ownername in the NSEC3 chain (ie. without the domain)
+ * \param[in] nsec3_rr The RR to read from
+ * \return The first label of the next owner name in the NSEC3 chain, or NULL on error 
+ */
+ldns_rdf *ldns_nsec3_next_owner(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns the bitmap specifying the covered types of the given NSEC3 RR
+ * \param[in] *nsec3_rr The RR to read from
+ * \return The covered type bitmap rdf
+ */
+ldns_rdf *ldns_nsec3_bitmap(const ldns_rr *nsec3_rr);
+
+/**
+ * Calculates the hashed name using the parameters of the given NSEC3 RR
+ * \param[in] *nsec The RR to use the parameters from
+ * \param[in] *name The owner name to calculate the hash for 
+ * \return The hashed owner name rdf, without the domain name
+ */
+ldns_rdf *ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name);
+
+/**
+ * Check if RR type t is enumerated and set in the RR type bitmap rdf.
+ * \param[in] bitmap the RR type bitmap rdf to look in
+ * \param[in] type the type to check for
+ * \return true when t is found and set, otherwise return false
+ */
+bool ldns_nsec_bitmap_covers_type(const ldns_rdf* bitmap, ldns_rr_type type);
+
+/**
+ * Checks if RR type t is enumerated in the type bitmap rdf and sets the bit.
+ * \param[in] bitmap the RR type bitmap rdf to look in
+ * \param[in] type the type to for which the bit to set
+ * \return LDNS_STATUS_OK on success. LDNS_STATUS_TYPE_NOT_IN_BITMAP is 
+ *         returned when the bitmap does not contain the bit to set.
+ */
+ldns_status ldns_nsec_bitmap_set_type(ldns_rdf* bitmap, ldns_rr_type type);
+
+/**
+ * Checks if RR type t is enumerated in the type bitmap rdf and clears the bit.
+ * \param[in] bitmap the RR type bitmap rdf to look in
+ * \param[in] type the type to for which the bit to clear
+ * \return LDNS_STATUS_OK on success. LDNS_STATUS_TYPE_NOT_IN_BITMAP is 
+ *         returned when the bitmap does not contain the bit to clear.
+ */
+ldns_status ldns_nsec_bitmap_clear_type(ldns_rdf* bitmap, ldns_rr_type type);
+
+/**
+ * Checks coverage of NSEC(3) RR name span
+ * Remember that nsec and name must both be in canonical form (ie use
+ * \ref ldns_rr2canonical and \ref ldns_dname2canonical prior to calling this
+ * function)
+ *
+ * \param[in] nsec The NSEC RR to check
+ * \param[in] name The owner dname to check, if the nsec record is a NSEC3 record, this should be the hashed name
+ * \return true if the NSEC RR covers the owner name
+ */
+bool ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name);
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * verify a packet 
+ * \param[in] p the packet
+ * \param[in] t the rr set type to check
+ * \param[in] o the rr set name to check
+ * \param[in] k list of keys
+ * \param[in] s list of sigs (may be null)
+ * \param[out] good_keys keys which validated the packet
+ * \return status 
+ * 
+ */
+ldns_status ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys);
+
+/**
+ * verify a packet 
+ * \param[in] p the packet
+ * \param[in] t the rr set type to check
+ * \param[in] o the rr set name to check
+ * \param[in] k list of keys
+ * \param[in] s list of sigs (may be null)
+ * \param[in] check_time the time for which the validation is performed
+ * \param[out] good_keys keys which validated the packet
+ * \return status 
+ * 
+ */
+ldns_status ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_list *k, ldns_rr_list *s, time_t check_time, ldns_rr_list *good_keys);
+
+#endif
+
+/**
+ * chains nsec3 list
+ */
+ldns_status
+ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs);
+
+/**
+ * compare for nsec3 sort
+ */
+int
+qsort_rr_compare_nsec3(const void *a, const void *b);
+
+/**
+ * sort nsec3 list
+ */
+void
+ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted);
+
+/** 
+ * Default callback function to always leave present signatures, and
+ * add new ones
+ * \param[in] sig The signature to check for removal (unused)
+ * \param[in] n Optional argument (unused)
+ * \return LDNS_SIGNATURE_LEAVE_ADD_NEW
+ */
+int ldns_dnssec_default_add_to_signatures(ldns_rr *sig, void *n);
+/** 
+ * Default callback function to always leave present signatures, and
+ * add no new ones for the keys of these signatures
+ * \param[in] sig The signature to check for removal (unused)
+ * \param[in] n Optional argument (unused)
+ * \return LDNS_SIGNATURE_LEAVE_NO_ADD
+ */
+int ldns_dnssec_default_leave_signatures(ldns_rr *sig, void *n);
+/** 
+ * Default callback function to always remove present signatures, but
+ * add no new ones
+ * \param[in] sig The signature to check for removal (unused)
+ * \param[in] n Optional argument (unused)
+ * \return LDNS_SIGNATURE_REMOVE_NO_ADD
+ */
+int ldns_dnssec_default_delete_signatures(ldns_rr *sig, void *n);
+/** 
+ * Default callback function to always leave present signatures, and
+ * add new ones
+ * \param[in] sig The signature to check for removal (unused)
+ * \param[in] n Optional argument (unused)
+ * \return LDNS_SIGNATURE_REMOVE_ADD_NEW
+ */
+int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n);
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * Converts the DSA signature from ASN1 representation (RFC2459, as 
+ * used by OpenSSL) to raw signature data as used in DNS (rfc2536)
+ *
+ * \param[in] sig The signature in RFC2459 format
+ * \param[in] sig_len The length of the signature
+ * \return a new rdf with the signature
+ */
+ldns_rdf *
+ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
+						  const long sig_len);
+
+/**
+ * Converts the RRSIG signature RDF (in rfc2536 format) to a buffer
+ * with the signature in rfc2459 format
+ *
+ * \param[out] target_buffer buffer to place the signature data
+ * \param[in] sig_rdf The signature rdf to convert
+ * \return LDNS_STATUS_OK on success, error code otherwise
+ */
+ldns_status
+ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+						  const ldns_rdf *sig_rdf);
+
+/**
+ * Converts the ECDSA signature from ASN1 representation (as 
+ * used by OpenSSL) to raw signature data as used in DNS
+ * This routine is only present if ldns is compiled with ecdsa support.
+ *
+ * \param[in] sig The signature in ASN1 format
+ * \param[in] sig_len The length of the signature
+ * \return a new rdf with the signature
+ */
+ldns_rdf *
+ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len);
+
+/**
+ * Converts the RRSIG signature RDF (from DNS) to a buffer with the 
+ * signature in ASN1 format as openssl uses it.
+ * This routine is only present if ldns is compiled with ecdsa support.
+ *
+ * \param[out] target_buffer buffer to place the signature data in ASN1.
+ * \param[in] sig_rdf The signature rdf to convert
+ * \return LDNS_STATUS_OK on success, error code otherwise
+ */
+ldns_status
+ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+        const ldns_rdf *sig_rdf);
+
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_DNSSEC_H */
diff --git a/ldns/include/ldns/dnssec_sign.h b/ldns/include/ldns/dnssec_sign.h
new file mode 100644
index 0000000..f51c7fb
--- /dev/null
+++ b/ldns/include/ldns/dnssec_sign.h
@@ -0,0 +1,383 @@
+/** dnssec_verify */
+
+#ifndef LDNS_DNSSEC_SIGN_H
+#define LDNS_DNSSEC_SIGN_H
+
+#include <ldns/dnssec.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* sign functions */
+
+/** Sign flag that makes DNSKEY type signed by all keys, not only by SEP keys*/
+#define LDNS_SIGN_DNSKEY_WITH_ZSK 1
+
+/**
+ * Create an empty RRSIG RR (i.e. without the actual signature data)
+ * \param[in] rrset The RRset to create the signature for
+ * \param[in] key The key that will create the signature
+ * \return signature rr
+ */
+ldns_rr *
+ldns_create_empty_rrsig(ldns_rr_list *rrset,
+                        ldns_key *key);
+
+/**
+ * Sign the buffer which contains the wiredata of an rrset, and the
+ * corresponding empty rrsig rr with the given key
+ * \param[in] sign_buf the buffer with data to sign
+ * \param[in] key the key to sign with
+ * \return an rdata field with the signature data
+ */
+ldns_rdf *
+ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *key);
+
+/**
+ * Sign an rrset
+ * \param[in] rrset the rrset
+ * \param[in] keys the keys to use
+ * \return a rr_list with the signatures
+ */
+ldns_rr_list *ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys);
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * Sign a buffer with the DSA key (hash with SHA1)
+ * \param[in] to_sign buffer with the data
+ * \param[in] key the key to use
+ * \return a ldns_rdf with the signed data
+ */
+ldns_rdf *ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key);
+
+/**
+ * Sign data with EVP (general method for different algorithms)
+ *
+ * \param[in] to_sign The ldns_buffer containing raw data that is
+ *                    to be signed
+ * \param[in] key The EVP_PKEY key structure to sign with
+ * \param[in] digest_type The digest algorithm to use in the creation of
+ *                        the signature
+ * \return ldns_rdf for the RRSIG ldns_rr
+ */
+ldns_rdf *ldns_sign_public_evp(ldns_buffer *to_sign,
+						 EVP_PKEY *key,
+						 const EVP_MD *digest_type);
+
+/**
+ * Sign a buffer with the RSA key (hash with SHA1)
+ * \param[in] to_sign buffer with the data
+ * \param[in] key the key to use
+ * \return a ldns_rdf with the signed data
+ */
+ldns_rdf *ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key);
+
+/**
+ * Sign a buffer with the RSA key (hash with MD5)
+ * \param[in] to_sign buffer with the data
+ * \param[in] key the key to use
+ * \return a ldns_rdf with the signed data
+ */
+ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially occluded (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account separately.
+ *
+ * When glue_list is given (not NULL), in the process of marking the names, all
+ * glue resource records will be pushed to that list, even glue at the delegation name.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \param[in] glue_list the list to which to push the glue rrs
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status
+ldns_dnssec_zone_mark_and_get_glue(
+		ldns_dnssec_zone *zone, ldns_rr_list *glue_list);
+
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially occluded (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account separately.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \return LDNS_STATUS_OK on succesful completion
+ */
+ldns_status
+ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone);
+
+/**
+ * Finds the first dnssec_name node in the rbtree that is not occluded.
+ * It *does* return names that are partially occluded.
+ *
+ * \param[in] node the first node to check
+ * \return the first node that has not been marked as glue, or NULL
+ * if not found (TODO: make that LDNS_RBTREE_NULL?)
+ */
+ldns_rbnode_t *ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node);
+
+/**
+ * Adds NSEC records to the given dnssec_zone
+ *
+ * \param[in] zone the zone to add the records to
+ * \param[in] new_rrs ldns_rr's created by this function are
+ *            added to this rr list, so the caller can free them later
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
+								  ldns_rr_list *new_rrs);
+
+/**
+ * Adds NSEC3 records to the zone
+ */
+ldns_status
+ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
+						 ldns_rr_list *new_rrs,
+						 uint8_t algorithm,
+						 uint8_t flags,
+						 uint16_t iterations,
+						 uint8_t salt_length,
+						 uint8_t *salt);
+
+/**
+ * remove signatures if callback function tells to
+ * 
+ * \param[in] signatures list of signatures to check, and
+ *            possibly remove, depending on the value of the
+ *            callback
+ * \param[in] key_list these are marked to be used or not,
+ *            on the return value of the callback
+ * \param[in] func this function is called to specify what to
+ *            do with each signature (and corresponding key)
+ * \param[in] arg Optional argument for the callback function
+ * \returns pointer to the new signatures rrs (the original
+ *          passed to this function may have been removed)
+ */
+ldns_dnssec_rrs *ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
+									  ldns_key_list *key_list,
+									  int (*func)(ldns_rr *, void *),
+									  void *arg);
+
+/**
+ * Adds signatures to the zone
+ *
+ * \param[in] zone the zone to add RRSIG Resource Records to
+ * \param[in] new_rrs the RRSIG RRs that are created are also
+ *            added to this list, so the caller can free them
+ *            later
+ * \param[in] key_list list of keys to sign with.
+ * \param[in] func Callback function to decide what keys to
+ *            use and what to do with old signatures
+ * \param[in] arg Optional argument for the callback function
+ * \param[in] flags option flags for signing process. 0 makes DNSKEY
+ * RRset signed with the minimal key set, that is only SEP keys are used
+ * for signing. If there are no SEP keys available, non-SEP keys will
+ * be used. LDNS_SIGN_DNSKEY_WITH_ZSK makes DNSKEY type signed with all
+ * keys. 0 is the default.
+ * \return LDNS_STATUS_OK on success, error otherwise
+ */
+ldns_status ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
+					ldns_rr_list *new_rrs,
+					ldns_key_list *key_list,
+					int (*func)(ldns_rr *, void*),
+					void *arg,
+					int flags);
+
+/**
+ * Adds signatures to the zone
+ *
+ * \param[in] zone the zone to add RRSIG Resource Records to
+ * \param[in] new_rrs the RRSIG RRs that are created are also
+ *            added to this list, so the caller can free them
+ *            later
+ * \param[in] key_list list of keys to sign with.
+ * \param[in] func Callback function to decide what keys to
+ *            use and what to do with old signatures
+ * \param[in] arg Optional argument for the callback function
+ * \return LDNS_STATUS_OK on success, error otherwise
+ */
+ldns_status ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
+								   ldns_rr_list *new_rrs,
+								   ldns_key_list *key_list,
+								   int (*func)(ldns_rr *, void*),
+								   void *arg);
+
+/**
+ * signs the given zone with the given keys
+ * 
+ * \param[in] zone the zone to sign
+ * \param[in] key_list the list of keys to sign the zone with
+ * \param[in] new_rrs newly created resource records are added to this list, to free them later
+ * \param[in] func callback function that decides what to do with old signatures
+ *            This function takes an ldns_rr* and an optional void *arg argument, and returns one of four values:
+ * LDNS_SIGNATURE_LEAVE_ADD_NEW:
+ * leave the signature and add a new one for the corresponding key
+ * LDNS_SIGNATURE_REMOVE_ADD_NEW:
+ * remove the signature and replace is with a new one from the same key
+ * LDNS_SIGNATURE_LEAVE_NO_ADD:
+ * leave the signature and do not add a new one with the corresponding key
+ * LDNS_SIGNATURE_REMOVE_NO_ADD:
+ * remove the signature and do not replace 
+ *
+ * \param[in] arg optional argument for the callback function
+ * \param[in] flags option flags for signing process. 0 makes DNSKEY
+ * RRset signed with the minimal key set, that is only SEP keys are used
+ * for signing. If there are no SEP keys available, non-SEP keys will
+ * be used. LDNS_SIGN_DNSKEY_WITH_ZSK makes DNSKEY type signed with all
+ * keys. 0 is the default.
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
+					ldns_rr_list *new_rrs,
+					ldns_key_list *key_list,
+					int (*func)(ldns_rr *, void *),
+					void *arg, 
+					int flags);
+
+/**
+ * signs the given zone with the given new zone, with NSEC3
+ *
+ * \param[in] zone the zone to sign
+ * \param[in] key_list the list of keys to sign the zone with
+ * \param[in] new_rrs newly created resource records are added to this list, to free them later
+ * \param[in] func callback function that decides what to do with old signatures
+ * \param[in] arg optional argument for the callback function
+ * \param[in] algorithm the NSEC3 hashing algorithm to use
+ * \param[in] flags NSEC3 flags
+ * \param[in] iterations the number of NSEC3 hash iterations to use
+ * \param[in] salt_length the length (in octets) of the NSEC3 salt
+ * \param[in] salt the NSEC3 salt data
+ * \param[in] signflags option flags for signing process. 0 is the default.
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
+				ldns_rr_list *new_rrs,
+				ldns_key_list *key_list,
+				int (*func)(ldns_rr *, void *),
+				void *arg,
+				uint8_t algorithm,
+				uint8_t flags,
+				uint16_t iterations,
+				uint8_t salt_length,
+				uint8_t *salt,
+				int signflags);
+
+/**
+ * signs the given zone with the given new zone, with NSEC3
+ *
+ * \param[in] zone the zone to sign
+ * \param[in] key_list the list of keys to sign the zone with
+ * \param[in] new_rrs newly created resource records are added to this list, to free them later
+ * \param[in] func callback function that decides what to do with old signatures
+ * \param[in] arg optional argument for the callback function
+ * \param[in] algorithm the NSEC3 hashing algorithm to use
+ * \param[in] flags NSEC3 flags
+ * \param[in] iterations the number of NSEC3 hash iterations to use
+ * \param[in] salt_length the length (in octets) of the NSEC3 salt
+ * \param[in] salt the NSEC3 salt data
+ * \param[in] signflags option flags for signing process. 0 is the default.
+ * \param[out] map a referenced rbtree pointer variable. The newly created 
+ *                 rbtree will contain mappings from hashed owner names to the 
+ *                 unhashed name.
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
+				ldns_rr_list *new_rrs,
+				ldns_key_list *key_list,
+				int (*func)(ldns_rr *, void *),
+				void *arg,
+				uint8_t algorithm,
+				uint8_t flags,
+				uint16_t iterations,
+				uint8_t salt_length,
+				uint8_t *salt,
+				int signflags,
+				ldns_rbtree_t **map
+				);
+
+
+/**
+ * signs the given zone with the given keys
+ * 
+ * \param[in] zone the zone to sign
+ * \param[in] key_list the list of keys to sign the zone with
+ * \param[in] new_rrs newly created resource records are added to this list, to free them later
+ * \param[in] func callback function that decides what to do with old signatures
+ *            This function takes an ldns_rr* and an optional void *arg argument, and returns one of four values:
+ * LDNS_SIGNATURE_LEAVE_ADD_NEW:
+ * leave the signature and add a new one for the corresponding key
+ * LDNS_SIGNATURE_REMOVE_ADD_NEW:
+ * remove the signature and replace is with a new one from the same key
+ * LDNS_SIGNATURE_LEAVE_NO_ADD:
+ * leave the signature and do not add a new one with the corresponding key
+ * LDNS_SIGNATURE_REMOVE_NO_ADD:
+ * remove the signature and do not replace 
+ *
+ * \param[in] arg optional argument for the callback function
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
+						    ldns_rr_list *new_rrs,
+						    ldns_key_list *key_list,
+						    int (*func)(ldns_rr *, void *),
+						    void *arg);
+
+/**
+ * signs the given zone with the given new zone, with NSEC3
+ *
+ * \param[in] zone the zone to sign
+ * \param[in] key_list the list of keys to sign the zone with
+ * \param[in] new_rrs newly created resource records are added to this list, to free them later
+ * \param[in] func callback function that decides what to do with old signatures
+ * \param[in] arg optional argument for the callback function
+ * \param[in] algorithm the NSEC3 hashing algorithm to use
+ * \param[in] flags NSEC3 flags
+ * \param[in] iterations the number of NSEC3 hash iterations to use
+ * \param[in] salt_length the length (in octets) of the NSEC3 salt
+ * \param[in] salt the NSEC3 salt data
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
+								ldns_rr_list *new_rrs,
+								ldns_key_list *key_list,
+								int (*func)(ldns_rr *, void *),
+								void *arg,
+								uint8_t algorithm,
+								uint8_t flags,
+								uint16_t iterations,
+								uint8_t salt_length,
+								uint8_t *salt);
+
+/**
+ * Signs the zone, and returns a newly allocated signed zone
+ * \param[in] zone the zone to sign
+ * \param[in] key_list list of keys to sign with
+ * \return signed zone
+ */
+ldns_zone *ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list);
+
+/**
+ * Signs the zone with NSEC3, and returns a newly allocated signed zone
+ * \param[in] zone the zone to sign
+ * \param[in] key_list list of keys to sign with
+ * \param[in] algorithm the NSEC3 hashing algorithm to use
+ * \param[in] flags NSEC3 flags
+ * \param[in] iterations the number of NSEC3 hash iterations to use
+ * \param[in] salt_length the length (in octets) of the NSEC3 salt
+ * \param[in] salt the NSEC3 salt data
+ * \return signed zone
+ */
+ldns_zone *ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
+ 
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ldns/include/ldns/dnssec_verify.h b/ldns/include/ldns/dnssec_verify.h
new file mode 100644
index 0000000..e8b1a91
--- /dev/null
+++ b/ldns/include/ldns/dnssec_verify.h
@@ -0,0 +1,857 @@
+/** dnssec_verify */
+
+#ifndef LDNS_DNSSEC_VERIFY_H
+#define LDNS_DNSSEC_VERIFY_H
+
+#define LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS 10
+
+#include <ldns/dnssec.h>
+#include <ldns/host2str.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Chain structure that contains all DNSSEC data needed to
+ * verify an rrset
+ */
+typedef struct ldns_dnssec_data_chain_struct ldns_dnssec_data_chain;
+struct ldns_dnssec_data_chain_struct
+{
+	ldns_rr_list *rrset;
+	ldns_rr_list *signatures;
+	ldns_rr_type parent_type;
+	ldns_dnssec_data_chain *parent;
+	ldns_pkt_rcode packet_rcode;
+	ldns_rr_type packet_qtype;
+	bool packet_nodata;
+};
+
+/**
+ * Creates a new dnssec_chain structure
+ * \return ldns_dnssec_data_chain *
+ */
+ldns_dnssec_data_chain *ldns_dnssec_data_chain_new(void);
+
+/**
+ * Frees a dnssec_data_chain structure
+ *
+ * \param[in] *chain The chain to free
+ */
+void ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain);
+
+/**
+ * Frees a dnssec_data_chain structure, and all data
+ * contained therein
+ *
+ * \param[in] *chain The dnssec_data_chain to free
+ */
+void ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain);
+
+/**
+ * Prints the dnssec_data_chain to the given file stream
+ * 
+ * \param[in] *out The file stream to print to
+ * \param[in] *chain The dnssec_data_chain to print
+ */
+void ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain);
+
+/**
+ * Prints the dnssec_data_chain to the given file stream
+ * 
+ * \param[in] *out The file stream to print to
+ * \param[in] *fmt The format of the textual representation
+ * \param[in] *chain The dnssec_data_chain to print
+ */
+void ldns_dnssec_data_chain_print_fmt(FILE *out, 
+		const ldns_output_format *fmt,
+		const ldns_dnssec_data_chain *chain);
+
+/**
+ * Build an ldns_dnssec_data_chain, which contains all
+ * DNSSEC data that is needed to derive the trust tree later
+ *
+ * The data_set will be cloned
+ *
+ * \param[in] *res resolver structure for further needed queries
+ * \param[in] qflags resolution flags
+ * \param[in] *data_set The original rrset where the chain ends
+ * \param[in] *pkt optional, can contain the original packet
+ * (and hence the sigs and maybe the key)
+ * \param[in] *orig_rr The original Resource Record
+ *
+ * \return the DNSSEC data chain
+ */
+ldns_dnssec_data_chain *ldns_dnssec_build_data_chain(ldns_resolver *res,
+										   const uint16_t qflags,
+										   const ldns_rr_list *data_set,
+										   const ldns_pkt *pkt,
+										   ldns_rr *orig_rr);
+
+/**
+ * Tree structure that contains the relation of DNSSEC data,
+ * and their cryptographic status.
+ *
+ * This tree is derived from a data_chain, and can be used
+ * to look whether there is a connection between an RRSET
+ * and a trusted key. The tree only contains pointers to the
+ * data_chain, and therefore one should *never* free() the
+ * data_chain when there is still a trust tree derived from
+ * that chain.
+ *
+ * Example tree:
+ *     key   key    key
+ *       \    |    /
+ *        \   |   /
+ *         \  |  /
+ *            ds
+ *            |
+ *           key
+ *            |
+ *           key
+ *            |
+ *            rr
+ *
+ * For each signature there is a parent; if the parent
+ * pointer is null, it couldn't be found and there was no
+ * denial; otherwise is a tree which contains either a
+ * DNSKEY, a DS, or a NSEC rr
+ */
+typedef struct ldns_dnssec_trust_tree_struct ldns_dnssec_trust_tree;
+struct ldns_dnssec_trust_tree_struct
+{
+	ldns_rr *rr;
+	/* the complete rrset this rr was in */
+	ldns_rr_list *rrset;
+	ldns_dnssec_trust_tree *parents[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
+	ldns_status parent_status[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
+	/** for debugging, add signatures too (you might want
+	    those if they contain errors) */
+	ldns_rr *parent_signature[LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS];
+	size_t parent_count;
+};
+
+/**
+ * Creates a new (empty) dnssec_trust_tree structure
+ *
+ * \return ldns_dnssec_trust_tree *
+ */
+ldns_dnssec_trust_tree *ldns_dnssec_trust_tree_new(void);
+
+/**
+ * Frees the dnssec_trust_tree recursively
+ *
+ * There is no deep free; all data in the trust tree
+ * consists of pointers to a data_chain
+ *
+ * \param[in] tree The tree to free
+ */
+void ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree);
+
+/**
+ * returns the depth of the trust tree
+ *
+ * \param[in] tree tree to calculate the depth of
+ * \return The depth of the tree
+ */
+size_t ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree);
+
+/**
+ * Prints the dnssec_trust_tree structure to the given file
+ * stream.
+ *
+ * If a link status is not LDNS_STATUS_OK; the status and
+ * relevant signatures are printed too
+ *
+ * \param[in] *out The file stream to print to
+ * \param[in] tree The trust tree to print
+ * \param[in] tabs Prepend each line with tabs*2 spaces
+ * \param[in] extended If true, add little explanation lines to the output
+ */
+void ldns_dnssec_trust_tree_print(FILE *out,
+	       	ldns_dnssec_trust_tree *tree,
+		size_t tabs,
+		bool extended);
+
+/**
+ * Prints the dnssec_trust_tree structure to the given file
+ * stream.
+ *
+ * If a link status is not LDNS_STATUS_OK; the status and
+ * relevant signatures are printed too
+ *
+ * \param[in] *out The file stream to print to
+ * \param[in] *fmt The format of the textual representation
+ * \param[in] tree The trust tree to print
+ * \param[in] tabs Prepend each line with tabs*2 spaces
+ * \param[in] extended If true, add little explanation lines to the output
+ */
+void ldns_dnssec_trust_tree_print_fmt(FILE *out,
+		const ldns_output_format *fmt,
+	       	ldns_dnssec_trust_tree *tree,
+		size_t tabs,
+		bool extended);
+
+/**
+ * Adds a trust tree as a parent for the given trust tree
+ *
+ * \param[in] *tree The tree to add the parent to
+ * \param[in] *parent The parent tree to add
+ * \param[in] *parent_signature The RRSIG relevant to this parent/child
+ *                              connection
+ * \param[in] parent_status The DNSSEC status for this parent, child and RRSIG
+ * \return LDNS_STATUS_OK if the addition succeeds, error otherwise
+ */
+ldns_status ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
+									 const ldns_dnssec_trust_tree *parent,
+									 const ldns_rr *parent_signature,
+									 const ldns_status parent_status);
+
+/**
+ * Generates a dnssec_trust_tree for the given rr from the
+ * given data_chain
+ *
+ * This does not clone the actual data; Don't free the
+ * data_chain before you are done with this tree
+ *
+ * \param[in] *data_chain The chain to derive the trust tree from
+ * \param[in] *rr The RR this tree will be about
+ * \return ldns_dnssec_trust_tree *
+ */
+ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree(
+                            ldns_dnssec_data_chain *data_chain,
+					   ldns_rr *rr);
+
+/**
+ * Generates a dnssec_trust_tree for the given rr from the
+ * given data_chain
+ *
+ * This does not clone the actual data; Don't free the
+ * data_chain before you are done with this tree
+ *
+ * \param[in] *data_chain The chain to derive the trust tree from
+ * \param[in] *rr The RR this tree will be about
+ * \param[in] check_time the time for which the validation is performed
+ * \return ldns_dnssec_trust_tree *
+ */
+ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree_time(
+		ldns_dnssec_data_chain *data_chain, 
+		ldns_rr *rr, time_t check_time);
+
+/**
+ * Sub function for derive_trust_tree that is used for a 'normal' rrset
+ *
+ * \param[in] new_tree The trust tree that we are building
+ * \param[in] data_chain The data chain containing the data for the trust tree
+ * \param[in] cur_sig_rr The currently relevant signature
+ */
+void ldns_dnssec_derive_trust_tree_normal_rrset(
+         ldns_dnssec_trust_tree *new_tree,
+	    ldns_dnssec_data_chain *data_chain,
+	    ldns_rr *cur_sig_rr);
+
+/**
+ * Sub function for derive_trust_tree that is used for a 'normal' rrset
+ *
+ * \param[in] new_tree The trust tree that we are building
+ * \param[in] data_chain The data chain containing the data for the trust tree
+ * \param[in] cur_sig_rr The currently relevant signature
+ * \param[in] check_time the time for which the validation is performed
+ */
+void ldns_dnssec_derive_trust_tree_normal_rrset_time(
+         ldns_dnssec_trust_tree *new_tree,
+	    ldns_dnssec_data_chain *data_chain,
+	    ldns_rr *cur_sig_rr, time_t check_time);
+
+
+/**
+ * Sub function for derive_trust_tree that is used for DNSKEY rrsets
+ *
+ * \param[in] new_tree The trust tree that we are building
+ * \param[in] data_chain The data chain containing the data for the trust tree
+ * \param[in] cur_rr The currently relevant DNSKEY RR
+ * \param[in] cur_sig_rr The currently relevant signature
+ */
+void ldns_dnssec_derive_trust_tree_dnskey_rrset(
+         ldns_dnssec_trust_tree *new_tree,
+	    ldns_dnssec_data_chain *data_chain,
+	    ldns_rr *cur_rr,
+	    ldns_rr *cur_sig_rr);
+
+/**
+ * Sub function for derive_trust_tree that is used for DNSKEY rrsets
+ *
+ * \param[in] new_tree The trust tree that we are building
+ * \param[in] data_chain The data chain containing the data for the trust tree
+ * \param[in] cur_rr The currently relevant DNSKEY RR
+ * \param[in] cur_sig_rr The currently relevant signature
+ * \param[in] check_time the time for which the validation is performed
+ */
+void ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
+         ldns_dnssec_trust_tree *new_tree,
+	    ldns_dnssec_data_chain *data_chain,
+	    ldns_rr *cur_rr, ldns_rr *cur_sig_rr,
+	    time_t check_time);
+
+/**
+ * Sub function for derive_trust_tree that is used for DS rrsets
+ *
+ * \param[in] new_tree The trust tree that we are building
+ * \param[in] data_chain The data chain containing the data for the trust tree
+ * \param[in] cur_rr The currently relevant DS RR
+ */
+void ldns_dnssec_derive_trust_tree_ds_rrset(
+         ldns_dnssec_trust_tree *new_tree,
+	    ldns_dnssec_data_chain *data_chain,
+	    ldns_rr *cur_rr);
+
+/**
+ * Sub function for derive_trust_tree that is used for DS rrsets
+ *
+ * \param[in] new_tree The trust tree that we are building
+ * \param[in] data_chain The data chain containing the data for the trust tree
+ * \param[in] cur_rr The currently relevant DS RR
+ * \param[in] check_time the time for which the validation is performed
+ */
+void ldns_dnssec_derive_trust_tree_ds_rrset_time(
+         ldns_dnssec_trust_tree *new_tree,
+	    ldns_dnssec_data_chain *data_chain,
+	    ldns_rr *cur_rr, time_t check_time);
+
+/**
+ * Sub function for derive_trust_tree that is used when there are no
+ * signatures
+ *
+ * \param[in] new_tree The trust tree that we are building
+ * \param[in] data_chain The data chain containing the data for the trust tree
+ */
+void ldns_dnssec_derive_trust_tree_no_sig(
+         ldns_dnssec_trust_tree *new_tree,
+	    ldns_dnssec_data_chain *data_chain);
+
+/**
+ * Sub function for derive_trust_tree that is used when there are no
+ * signatures
+ *
+ * \param[in] new_tree The trust tree that we are building
+ * \param[in] data_chain The data chain containing the data for the trust tree
+ * \param[in] check_time the time for which the validation is performed
+ */
+void ldns_dnssec_derive_trust_tree_no_sig_time(
+         ldns_dnssec_trust_tree *new_tree,
+	    ldns_dnssec_data_chain *data_chain,
+	    time_t check_time);
+
+
+/**
+ * Returns OK if there is a trusted path in the tree to one of 
+ * the DNSKEY or DS RRs in the given list
+ *
+ * \param *tree The trust tree so search
+ * \param *keys A ldns_rr_list of DNSKEY and DS rrs to look for
+ *
+ * \return LDNS_STATUS_OK if there is a trusted path to one of
+ *                        the keys, or the *first* error encountered
+ *                        if there were no paths
+ */
+ldns_status ldns_dnssec_trust_tree_contains_keys(
+			 ldns_dnssec_trust_tree *tree,
+			 ldns_rr_list *keys);
+
+/**
+ * Verifies a list of signatures for one rrset.
+ *
+ * \param[in] rrset the rrset to verify
+ * \param[in] rrsig a list of signatures to check
+ * \param[in] keys a list of keys to check with
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
+ *                        from keys that validate one of the signatures
+ *                        are added to it
+ * \return status LDNS_STATUS_OK if there is at least one correct key
+ */
+ldns_status ldns_verify(ldns_rr_list *rrset,
+				    ldns_rr_list *rrsig,
+				    const ldns_rr_list *keys,
+				    ldns_rr_list *good_keys);	
+
+/**
+ * Verifies a list of signatures for one rrset.
+ *
+ * \param[in] rrset the rrset to verify
+ * \param[in] rrsig a list of signatures to check
+ * \param[in] keys a list of keys to check with
+ * \param[in] check_time the time for which the validation is performed
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
+ *                        from keys that validate one of the signatures
+ *                        are added to it
+ * \return status LDNS_STATUS_OK if there is at least one correct key
+ */
+ldns_status ldns_verify_time(ldns_rr_list *rrset,
+				    ldns_rr_list *rrsig,
+				    const ldns_rr_list *keys,
+				    time_t check_time,
+				    ldns_rr_list *good_keys);	
+
+
+/**
+ * Verifies a list of signatures for one rrset, but disregard the time.
+ * Inception and Expiration are not checked.
+ *
+ * \param[in] rrset the rrset to verify
+ * \param[in] rrsig a list of signatures to check
+ * \param[in] keys a list of keys to check with
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
+ *                        from keys that validate one of the signatures
+ *                        are added to it
+ * \return status LDNS_STATUS_OK if there is at least one correct key
+ */
+ldns_status ldns_verify_notime(ldns_rr_list *rrset,
+				    ldns_rr_list *rrsig,
+				    const ldns_rr_list *keys,
+				    ldns_rr_list *good_keys);	
+
+/**
+ * Tries to build an authentication chain from the given 
+ * keys down to the queried domain.
+ *
+ * If we find a valid trust path, return the valid keys for the domain.
+ * 
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \param[out] status pointer to the status variable where the result
+ *                    code will be stored
+ * \return the set of trusted keys for the domain, or NULL if no 
+ *         trust path could be built.
+ */
+ldns_rr_list *ldns_fetch_valid_domain_keys(const ldns_resolver * res,
+								   const ldns_rdf * domain,
+								   const ldns_rr_list * keys,
+								   ldns_status *status);
+
+/**
+ * Tries to build an authentication chain from the given 
+ * keys down to the queried domain.
+ *
+ * If we find a valid trust path, return the valid keys for the domain.
+ * 
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \param[in] check_time the time for which the validation is performed
+ * \param[out] status pointer to the status variable where the result
+ *                    code will be stored
+ * \return the set of trusted keys for the domain, or NULL if no 
+ *         trust path could be built.
+ */
+ldns_rr_list *ldns_fetch_valid_domain_keys_time(const ldns_resolver * res,
+		const ldns_rdf * domain, const ldns_rr_list * keys,
+		time_t check_time, ldns_status *status);
+
+
+/**
+ * Validates the DNSKEY RRset for the given domain using the provided 
+ * trusted keys.
+ *
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \return the set of trusted keys for the domain, or NULL if the RRSET
+ *         could not be validated
+ */
+ldns_rr_list *ldns_validate_domain_dnskey (const ldns_resolver *res,
+								   const ldns_rdf *domain,
+								   const ldns_rr_list *keys);
+
+/**
+ * Validates the DNSKEY RRset for the given domain using the provided 
+ * trusted keys.
+ *
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \param[in] check_time the time for which the validation is performed
+ * \return the set of trusted keys for the domain, or NULL if the RRSET
+ *         could not be validated
+ */
+ldns_rr_list *ldns_validate_domain_dnskey_time(
+		const ldns_resolver *res, const ldns_rdf *domain, 
+		const ldns_rr_list *keys, time_t check_time);
+
+
+/**
+ * Validates the DS RRset for the given domain using the provided trusted keys.
+ *
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
+ */
+ldns_rr_list *ldns_validate_domain_ds(const ldns_resolver *res,
+							   const ldns_rdf *
+							   domain,
+							   const ldns_rr_list * keys);
+
+/**
+ * Validates the DS RRset for the given domain using the provided trusted keys.
+ *
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \param[in] check_time the time for which the validation is performed
+ * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
+ */
+ldns_rr_list *ldns_validate_domain_ds_time(
+		const ldns_resolver *res, const ldns_rdf *domain, 
+		const ldns_rr_list * keys, time_t check_time);
+
+
+/**
+ * Verifies a list of signatures for one RRset using a valid trust path.
+ *
+ * \param[in] res the current resolver
+ * \param[in] rrset the rrset to verify
+ * \param[in] rrsigs a list of signatures to check
+ * \param[out] validating_keys  if this is a (initialized) list, the
+ *                              keys from keys that validate one of
+ *                              the signatures are added to it
+ * \return status LDNS_STATUS_OK if there is at least one correct key
+ */
+ldns_status ldns_verify_trusted(ldns_resolver *res,
+						  ldns_rr_list *rrset,
+						  ldns_rr_list *rrsigs,
+						  ldns_rr_list *validating_keys);
+
+/**
+ * Verifies a list of signatures for one RRset using a valid trust path.
+ *
+ * \param[in] res the current resolver
+ * \param[in] rrset the rrset to verify
+ * \param[in] rrsigs a list of signatures to check
+ * \param[in] check_time the time for which the validation is performed
+ * \param[out] validating_keys  if this is a (initialized) list, the
+ *                              keys from keys that validate one of
+ *                              the signatures are added to it
+ * \return status LDNS_STATUS_OK if there is at least one correct key
+ */
+ldns_status ldns_verify_trusted_time(
+		ldns_resolver *res, ldns_rr_list *rrset, 
+		ldns_rr_list *rrsigs, time_t check_time,
+		ldns_rr_list *validating_keys);
+
+
+/**
+ * denial is not just a river in egypt
+ *
+ * \param[in] rr The (query) RR to check the denial of existence for
+ * \param[in] nsecs The list of NSEC RRs that are supposed to deny the
+ *                  existence of the RR
+ * \param[in] rrsigs The RRSIG RR covering the NSEC RRs
+ * \return LDNS_STATUS_OK if the NSEC RRs deny the existence, error code
+ *                        containing the reason they do not otherwise
+ */
+ldns_status ldns_dnssec_verify_denial(ldns_rr *rr,
+							   ldns_rr_list *nsecs,
+							   ldns_rr_list *rrsigs);
+
+/**
+ * Denial of existence using NSEC3 records
+ * Since NSEC3 is a bit more complicated than normal denial, some
+ * context arguments are needed
+ *
+ * \param[in] rr The (query) RR to check the denial of existence for
+ * \param[in] nsecs The list of NSEC3 RRs that are supposed to deny the
+ *                  existence of the RR
+ * \param[in] rrsigs The RRSIG rr covering the NSEC RRs
+ * \param[in] packet_rcode The RCODE value of the packet that provided the
+ *                         NSEC3 RRs
+ * \param[in] packet_qtype The original query RR type
+ * \param[in] packet_nodata True if the providing packet had an empty ANSWER
+ *                          section
+ * \return LDNS_STATUS_OK if the NSEC3 RRs deny the existence, error code
+ *                        containing the reason they do not otherwise
+ */
+ldns_status ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
+								    ldns_rr_list *nsecs,
+								    ldns_rr_list *rrsigs,
+								    ldns_pkt_rcode packet_rcode,
+								    ldns_rr_type packet_qtype,
+								    bool packet_nodata);
+
+/**
+ * Same as ldns_status ldns_dnssec_verify_denial_nsec3 but also returns
+ * the nsec rr that matched.
+ *
+ * \param[in] rr The (query) RR to check the denial of existence for
+ * \param[in] nsecs The list of NSEC3 RRs that are supposed to deny the
+ *                  existence of the RR
+ * \param[in] rrsigs The RRSIG rr covering the NSEC RRs
+ * \param[in] packet_rcode The RCODE value of the packet that provided the
+ *                         NSEC3 RRs
+ * \param[in] packet_qtype The original query RR type
+ * \param[in] packet_nodata True if the providing packet had an empty ANSWER
+ *                          section
+ * \param[in] match On match, the given (reference to a) pointer will be set 
+ *                  to point to the matching nsec resource record.
+ * \return LDNS_STATUS_OK if the NSEC3 RRs deny the existence, error code
+ *                        containing the reason they do not otherwise
+ */
+ldns_status ldns_dnssec_verify_denial_nsec3_match(ldns_rr *rr,
+						  ldns_rr_list *nsecs,
+						  ldns_rr_list *rrsigs,
+						  ldns_pkt_rcode packet_rcode,
+						  ldns_rr_type packet_qtype,
+						  bool packet_nodata,
+						  ldns_rr **match);
+/**
+ * Verifies the already processed data in the buffers
+ * This function should probably not be used directly.
+ *
+ * \param[in] rawsig_buf Buffer containing signature data to use
+ * \param[in] verify_buf Buffer containing data to verify
+ * \param[in] key_buf Buffer containing key data to use
+ * \param[in] algo Signing algorithm
+ * \return status LDNS_STATUS_OK if the data verifies. Error if not.
+ */
+ldns_status ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf,
+							   ldns_buffer *verify_buf,
+							   ldns_buffer *key_buf,
+							   uint8_t algo);
+
+/**
+ * Like ldns_verify_rrsig_buffers, but uses raw data.
+ *
+ * \param[in] sig signature data to use
+ * \param[in] siglen length of signature data to use
+ * \param[in] verify_buf Buffer containing data to verify
+ * \param[in] key key data to use
+ * \param[in] keylen length of key data to use
+ * \param[in] algo Signing algorithm
+ * \return status LDNS_STATUS_OK if the data verifies. Error if not.
+ */
+ldns_status ldns_verify_rrsig_buffers_raw(unsigned char* sig,
+								  size_t siglen, 
+								  ldns_buffer *verify_buf,
+								  unsigned char* key,
+								  size_t keylen, 
+								  uint8_t algo);
+
+/**
+ * Verifies an rrsig. All keys in the keyset are tried.
+ * \param[in] rrset the rrset to check
+ * \param[in] rrsig the signature of the rrset
+ * \param[in] keys the keys to try
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
+ *                        from keys that validate one of the signatures
+ *                        are added to it
+ * \return a list of keys which validate the rrsig + rrset. Returns
+ * status LDNS_STATUS_OK if at least one key matched. Else an error.
+ */
+ldns_status ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
+							   ldns_rr *rrsig,
+							   const ldns_rr_list *keys,
+							   ldns_rr_list *good_keys);
+
+/**
+ * Verifies an rrsig. All keys in the keyset are tried.
+ * \param[in] rrset the rrset to check
+ * \param[in] rrsig the signature of the rrset
+ * \param[in] keys the keys to try
+ * \param[in] check_time the time for which the validation is performed
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
+ *                        from keys that validate one of the signatures
+ *                        are added to it
+ * \return a list of keys which validate the rrsig + rrset. Returns
+ * status LDNS_STATUS_OK if at least one key matched. Else an error.
+ */
+ldns_status ldns_verify_rrsig_keylist_time(
+		ldns_rr_list *rrset, ldns_rr *rrsig, 
+		const ldns_rr_list *keys, time_t check_time,
+	       	ldns_rr_list *good_keys);
+
+
+/**
+ * Verifies an rrsig. All keys in the keyset are tried. Time is not checked.
+ * \param[in] rrset the rrset to check
+ * \param[in] rrsig the signature of the rrset
+ * \param[in] keys the keys to try
+ * \param[out] good_keys  if this is a (initialized) list, the pointer to keys
+ *                        from keys that validate one of the signatures
+ *                        are added to it
+ * \return a list of keys which validate the rrsig + rrset. Returns
+ * status LDNS_STATUS_OK if at least one key matched. Else an error.
+ */
+ldns_status ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
+							   ldns_rr *rrsig,
+							   const ldns_rr_list *keys,
+							   ldns_rr_list *good_keys);
+
+/**
+ * verify an rrsig with 1 key
+ * \param[in] rrset the rrset
+ * \param[in] rrsig the rrsig to verify
+ * \param[in] key the key to use
+ * \return status message wether verification succeeded.
+ */
+ldns_status ldns_verify_rrsig(ldns_rr_list *rrset,
+						ldns_rr *rrsig,
+						ldns_rr *key);
+
+
+/**
+ * verify an rrsig with 1 key
+ * \param[in] rrset the rrset
+ * \param[in] rrsig the rrsig to verify
+ * \param[in] key the key to use
+ * \param[in] check_time the time for which the validation is performed
+ * \return status message wether verification succeeded.
+ */
+ldns_status ldns_verify_rrsig_time(
+		ldns_rr_list *rrset, ldns_rr *rrsig, 
+		ldns_rr *key, time_t check_time);
+
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * verifies a buffer with signature data for a buffer with rrset data 
+ * with an EVP_PKEY
+ *
+ * \param[in] sig the signature data
+ * \param[in] rrset the rrset data, sorted and processed for verification
+ * \param[in] key the EVP key structure
+ * \param[in] digest_type The digest type of the signature
+ */
+ldns_status ldns_verify_rrsig_evp(ldns_buffer *sig,
+						    ldns_buffer *rrset,
+						    EVP_PKEY *key,
+						    const EVP_MD *digest_type);
+
+/**
+ * Like ldns_verify_rrsig_evp, but uses raw signature data.
+ * \param[in] sig the signature data, wireformat uncompressed
+ * \param[in] siglen length of the signature data
+ * \param[in] rrset the rrset data, sorted and processed for verification
+ * \param[in] key the EVP key structure
+ * \param[in] digest_type The digest type of the signature
+ */
+ldns_status ldns_verify_rrsig_evp_raw(unsigned char *sig,
+							   size_t siglen,
+							   ldns_buffer *rrset,
+							   EVP_PKEY *key,
+							   const EVP_MD *digest_type);
+#endif
+
+/**
+ * verifies a buffer with signature data (DSA) for a buffer with rrset data 
+ * with a buffer with key data.
+ *
+ * \param[in] sig the signature data
+ * \param[in] rrset the rrset data, sorted and processed for verification
+ * \param[in] key the key data
+ */
+ldns_status ldns_verify_rrsig_dsa(ldns_buffer *sig,
+						    ldns_buffer *rrset,
+						    ldns_buffer *key);
+
+/**
+ * verifies a buffer with signature data (RSASHA1) for a buffer with rrset data 
+ * with a buffer with key data.
+ *
+ * \param[in] sig the signature data
+ * \param[in] rrset the rrset data, sorted and processed for verification
+ * \param[in] key the key data
+ */
+ldns_status ldns_verify_rrsig_rsasha1(ldns_buffer *sig,
+							   ldns_buffer *rrset,
+							   ldns_buffer *key);
+
+/**
+ * verifies a buffer with signature data (RSAMD5) for a buffer with rrset data 
+ * with a buffer with key data.
+ *
+ * \param[in] sig the signature data
+ * \param[in] rrset the rrset data, sorted and processed for verification
+ * \param[in] key the key data
+ */
+ldns_status ldns_verify_rrsig_rsamd5(ldns_buffer *sig,
+							  ldns_buffer *rrset,
+							  ldns_buffer *key);
+
+/**
+ * Like ldns_verify_rrsig_dsa, but uses raw signature and key data.
+ * \param[in] sig raw uncompressed wireformat signature data
+ * \param[in] siglen length of signature data
+ * \param[in] rrset ldns buffer with prepared rrset data.
+ * \param[in] key raw uncompressed wireformat key data
+ * \param[in] keylen length of key data
+ */
+ldns_status ldns_verify_rrsig_dsa_raw(unsigned char* sig,
+							   size_t siglen,
+							   ldns_buffer* rrset,
+							   unsigned char* key,
+							   size_t keylen);
+
+/**
+ * Like ldns_verify_rrsig_rsasha1, but uses raw signature and key data.
+ * \param[in] sig raw uncompressed wireformat signature data
+ * \param[in] siglen length of signature data
+ * \param[in] rrset ldns buffer with prepared rrset data.
+ * \param[in] key raw uncompressed wireformat key data
+ * \param[in] keylen length of key data
+ */
+ldns_status ldns_verify_rrsig_rsasha1_raw(unsigned char* sig,
+								  size_t siglen,
+								  ldns_buffer* rrset,
+								  unsigned char* key,
+								  size_t keylen);
+
+/**
+ * Like ldns_verify_rrsig_rsasha256, but uses raw signature and key data.
+ * \param[in] sig raw uncompressed wireformat signature data
+ * \param[in] siglen length of signature data
+ * \param[in] rrset ldns buffer with prepared rrset data.
+ * \param[in] key raw uncompressed wireformat key data
+ * \param[in] keylen length of key data
+ */
+
+ldns_status ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
+								    size_t siglen,
+								    ldns_buffer* rrset,
+								    unsigned char* key,
+								    size_t keylen);
+
+/**
+ * Like ldns_verify_rrsig_rsasha512, but uses raw signature and key data.
+ * \param[in] sig raw uncompressed wireformat signature data
+ * \param[in] siglen length of signature data
+ * \param[in] rrset ldns buffer with prepared rrset data.
+ * \param[in] key raw uncompressed wireformat key data
+ * \param[in] keylen length of key data
+ */
+ldns_status ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
+								    size_t siglen,
+								    ldns_buffer* rrset,
+								    unsigned char* key,
+								    size_t keylen);
+
+/**
+ * Like ldns_verify_rrsig_rsamd5, but uses raw signature and key data.
+ * \param[in] sig raw uncompressed wireformat signature data
+ * \param[in] siglen length of signature data
+ * \param[in] rrset ldns buffer with prepared rrset data.
+ * \param[in] key raw uncompressed wireformat key data
+ * \param[in] keylen length of key data
+ */
+ldns_status ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
+								 size_t siglen,
+								 ldns_buffer* rrset,
+								 unsigned char* key,
+								 size_t keylen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/ldns/include/ldns/dnssec_zone.h b/ldns/include/ldns/dnssec_zone.h
new file mode 100644
index 0000000..b794f94
--- /dev/null
+++ b/ldns/include/ldns/dnssec_zone.h
@@ -0,0 +1,483 @@
+/*
+ * special zone file structures and functions for better dnssec handling
+ *
+ * A zone contains a SOA dnssec_zone_rrset, and an AVL tree of 'normal'
+ * dnssec_zone_rrsets, indexed by name and type
+ */
+
+#ifndef LDNS_DNSSEC_ZONE_H
+#define LDNS_DNSSEC_ZONE_H
+ 
+#include <ldns/rbtree.h>
+#include <ldns/host2str.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Singly linked list of rrs
+ */
+typedef struct ldns_struct_dnssec_rrs ldns_dnssec_rrs;
+struct ldns_struct_dnssec_rrs
+{
+	ldns_rr *rr;
+	ldns_dnssec_rrs *next;
+};
+
+/**
+ * Singly linked list of RRsets
+ */
+typedef struct ldns_struct_dnssec_rrsets ldns_dnssec_rrsets;
+struct ldns_struct_dnssec_rrsets
+{
+	ldns_dnssec_rrs *rrs;
+	ldns_rr_type type;
+	ldns_dnssec_rrs *signatures;
+	ldns_dnssec_rrsets *next;
+};
+
+/**
+ * Structure containing all resource records for a domain name
+ * Including the derived NSEC3, if present
+ */
+typedef struct ldns_struct_dnssec_name ldns_dnssec_name;
+struct ldns_struct_dnssec_name
+{
+	/**
+	 * pointer to a dname containing the name.
+	 * Usually points to the owner name of the first RR of the first RRset
+	 */
+	ldns_rdf *name;
+	/** 
+	 * Usually, the name is a pointer to the owner name of the first rr for
+	 * this name, but sometimes there is no actual data to point to, 
+	 * for instance in
+	 * names representing empty nonterminals. If so, set alloced to true to
+	 * indicate that this data must also be freed when the name is freed
+	 */
+	bool name_alloced;
+	/**
+	 * The rrsets for this name
+	 */
+	ldns_dnssec_rrsets *rrsets;
+	/**
+	 * NSEC pointing to the next name (or NSEC3 pointing to the next NSEC3)
+	 */
+	ldns_rr *nsec;
+	/**
+	 * signatures for the NSEC record
+	 */
+	ldns_dnssec_rrs *nsec_signatures;
+	/**
+	 * Unlike what the name is_glue suggests, this field is set to true by
+	 * ldns_dnssec_zone_mark_glue() or ldns_dnssec_zone_mark_and_get_glue()
+	 * when the name, this dnssec_name struct represents, is occluded.
+	 * Names that contain other occluded rrsets and records with glue on
+	 * the delegation point will NOT have this bool set to true.
+	 * This field should NOT be read directly, but only via the 
+	 * ldns_dnssec_name_is_glue() function!
+	 */
+	bool is_glue;
+	/**
+	 * pointer to store the hashed name (only used when in an NSEC3 zone
+	 */
+	ldns_rdf *hashed_name;
+};
+
+/**
+ * Structure containing a dnssec zone
+ */
+struct ldns_struct_dnssec_zone {
+	/** points to the name containing the SOA RR */
+	ldns_dnssec_name *soa;
+	/** tree of ldns_dnssec_names */
+	ldns_rbtree_t *names;
+	/** tree of ldns_dnssec_names by nsec3 hashes (when applicible) */
+	ldns_rbtree_t *hashed_names;
+	/** points to the first added NSEC3 rr whose parameters will be 
+	 *  assumed for all subsequent NSEC3 rr's and which will be used
+	 *  to calculate hashed names
+	 */
+	ldns_rr *_nsec3params;
+};
+typedef struct ldns_struct_dnssec_zone ldns_dnssec_zone;
+
+/**
+ * Creates a new entry for 1 pointer to an rr and 1 pointer to the next rrs
+ * \return the allocated data
+ */
+ldns_dnssec_rrs *ldns_dnssec_rrs_new(void);
+
+/**
+ * Frees the list of rrs, but *not* the individual ldns_rr records
+ * contained in the list
+ * 
+ * \param[in] rrs the data structure to free
+ */
+void ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs);
+
+/**
+ * Frees the list of rrs, and the individual ldns_rr records
+ * contained in the list
+ * 
+ * \param[in] rrs the data structure to free
+ */
+void ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs);
+
+/**
+ * Adds an RR to the list of RRs. The list will remain ordered.
+ * If an equal RR already exists, this RR will not be added.
+ *
+ * \param[in] rrs the list to add to
+ * \param[in] rr the RR to add
+ * \return LDNS_STATUS_OK on success
+ */
+ldns_status ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr);
+
+/**
+ * Prints the given rrs to the file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] rrs the list of RRs to print
+ */
+void ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs);
+
+/**
+ * Prints the given rrs to the file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] rrs the list of RRs to print
+ */
+void ldns_dnssec_rrs_print_fmt(FILE *out, 
+		const ldns_output_format *fmt, ldns_dnssec_rrs *rrs);
+
+/**
+ * Creates a new list (entry) of RRsets
+ * \return the newly allocated structure
+ */
+ldns_dnssec_rrsets *ldns_dnssec_rrsets_new(void);
+
+/**
+ * Frees the list of rrsets and their rrs, but *not* the ldns_rr
+ * records in the sets
+ *
+ * \param[in] rrsets the data structure to free
+ */
+void ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets);
+
+/**
+ * Frees the list of rrsets and their rrs, and the ldns_rr
+ * records in the sets
+ *
+ * \param[in] rrsets the data structure to free
+ */
+void ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets);
+
+/**
+ * Returns the rr type of the rrset (that is head of the given list)
+ *
+ * \param[in] rrsets the rrset to get the type of
+ * \return the rr type
+ */
+ldns_rr_type ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets);
+
+/**
+ * Sets the RR type of the rrset (that is head of the given list)
+ *
+ * \param[in] rrsets the rrset to set the type of
+ * \param[in] type the type to set
+ * \return LDNS_STATUS_OK on success
+ */
+ldns_status ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
+					   ldns_rr_type type);
+
+/**
+ * Add an ldns_rr to the corresponding RRset in the given list of RRsets.
+ * If it is not present, add it as a new RRset with 1 record.
+ *
+ * \param[in] rrsets the list of rrsets to add the RR to
+ * \param[in] rr the rr to add to the list of rrsets
+ * \return LDNS_STATUS_OK on success
+ */
+ldns_status ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr);
+
+/**
+ * Print the given list of rrsets to the fiven file descriptor
+ * 
+ * \param[in] out the file descriptor to print to
+ * \param[in] rrsets the list of RRsets to print
+ * \param[in] follow if set to false, only print the first RRset
+ */ 
+void ldns_dnssec_rrsets_print(FILE *out,
+		ldns_dnssec_rrsets *rrsets,
+		bool follow);
+
+/**
+ * Print the given list of rrsets to the fiven file descriptor
+ * 
+ * \param[in] out the file descriptor to print to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] rrsets the list of RRsets to print
+ * \param[in] follow if set to false, only print the first RRset
+ */ 
+void ldns_dnssec_rrsets_print_fmt(FILE *out,
+		const ldns_output_format *fmt,
+		ldns_dnssec_rrsets *rrsets,
+		bool follow);
+
+
+/**
+ * Create a new data structure for a dnssec name
+ * \return the allocated structure
+ */
+ldns_dnssec_name *ldns_dnssec_name_new(void);
+
+/**
+ * Create a new data structure for a dnssec name for the given RR
+ *
+ * \param[in] rr the RR to derive properties from, and to add to the name
+ */
+ldns_dnssec_name *ldns_dnssec_name_new_frm_rr(ldns_rr *rr);
+
+/**
+ * Frees the name structure and its rrs and rrsets.
+ * Individual ldns_rr records therein are not freed
+ *
+ * \param[in] name the structure to free
+ */
+void ldns_dnssec_name_free(ldns_dnssec_name *name);
+
+/**
+ * Frees the name structure and its rrs and rrsets.
+ * Individual ldns_rr records contained in the name are also freed
+ *
+ * \param[in] name the structure to free
+ */
+void ldns_dnssec_name_deep_free(ldns_dnssec_name *name);
+
+/**
+ * Returns the domain name of the given dnssec_name structure
+ *
+ * \param[in] name the dnssec name to get the domain name from
+ * \return the domain name
+ */
+ldns_rdf *ldns_dnssec_name_name(ldns_dnssec_name *name);
+
+
+/**
+ * Sets the domain name of the given dnssec_name structure
+ *
+ * \param[in] name the dnssec name to set the domain name of
+ * \param[in] dname the domain name to set it to. This data is *not* copied.
+ */
+void ldns_dnssec_name_set_name(ldns_dnssec_name *name,
+						 ldns_rdf *dname);
+/**
+ * Returns if dnssec_name structure is marked as glue.
+ * The ldns_dnssec_zone_mark_glue() function has to be called on a zone before
+ * using this function.
+ * Only names that have only glue rrsets will be marked.
+ * Names that have other occluded rrsets and names containing glue on the 
+ * delegation point will NOT be marked!
+ *
+ * \param[in] name the dnssec name to get the domain name from
+ * \return true if the structure is marked as glue, false otherwise.
+ */
+bool ldns_dnssec_name_is_glue(ldns_dnssec_name *name);
+
+/**
+ * Sets the NSEC(3) RR of the given dnssec_name structure
+ *
+ * \param[in] name the dnssec name to set the domain name of
+ * \param[in] nsec the nsec rr to set it to. This data is *not* copied.
+ */
+void ldns_dnssec_name_set_nsec(ldns_dnssec_name *name, ldns_rr *nsec);
+
+/**
+ * Compares the domain names of the two arguments in their
+ * canonical ordening.
+ * 
+ * \param[in] a The first dnssec_name to compare
+ * \param[in] b The second dnssec_name to compare
+ * \return -1 if the domain name of a comes before that of b in canonical
+ *            ordening, 1 if it is the other way around, and 0 if they are
+ *            equal
+ */
+int ldns_dnssec_name_cmp(const void *a, const void *b);
+
+/**
+ * Inserts the given rr at the right place in the current dnssec_name
+ * No checking is done whether the name matches
+ *
+ * \param[in] name The ldns_dnssec_name to add the RR to
+ * \param[in] rr The RR to add
+ * \return LDNS_STATUS_OK on success, error code otherwise
+ */
+ldns_status ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
+							 ldns_rr *rr);
+
+/**
+ * Find the RRset with the given type in within this name structure
+ *
+ * \param[in] name the name to find the RRset in
+ * \param[in] type the type of the RRset to find
+ * \return the RRset, or NULL if not present
+ */
+ldns_dnssec_rrsets *ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
+									   ldns_rr_type type);
+
+/**
+ * Find the RRset with the given name and type in the zone
+ *
+ * \param[in] zone the zone structure to find the RRset in
+ * \param[in] dname the domain name of the RRset to find
+ * \param[in] type the type of the RRset to find
+ * \return the RRset, or NULL if not present
+ */
+ldns_dnssec_rrsets *ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
+									   ldns_rdf *dname,
+									   ldns_rr_type type);
+
+/**
+ * Prints the RRs in the  dnssec name structure to the given
+ * file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] name the name structure to print the contents of
+ */
+void ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name);
+
+/**
+ * Prints the RRs in the  dnssec name structure to the given
+ * file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] name the name structure to print the contents of
+ */
+void ldns_dnssec_name_print_fmt(FILE *out, 
+		const ldns_output_format *fmt, ldns_dnssec_name *name);
+
+/**
+ * Creates a new dnssec_zone structure
+ * \return the allocated structure
+ */
+ldns_dnssec_zone *ldns_dnssec_zone_new(void);
+
+/**
+ * Create a new dnssec zone from a file.
+ * \param[out] z the new zone
+ * \param[in] *fp the filepointer to use
+ * \param[in] *origin the zones' origin
+ * \param[in] c default class to use (IN)
+ * \param[in] ttl default ttl to use
+ *
+ * \return ldns_status mesg with an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp,
+		ldns_rdf* origin, uint32_t ttl, ldns_rr_class c);
+
+/**
+ * Create a new dnssec zone from a file, keep track of the line numbering
+ * \param[out] z the new zone
+ * \param[in] *fp the filepointer to use
+ * \param[in] *origin the zones' origin
+ * \param[in] ttl default ttl to use
+ * \param[in] c default class to use (IN)
+ * \param[out] line_nr used for error msg, to get to the line number
+ *
+ * \return ldns_status mesg with an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp,
+		ldns_rdf* origin, uint32_t ttl, ldns_rr_class c, int* line_nr);
+
+/**
+ * Frees the given zone structure, and its rbtree of dnssec_names
+ * Individual ldns_rr RRs within those names are *not* freed
+ * \param[in] *zone the zone to free
+ */ 
+void ldns_dnssec_zone_free(ldns_dnssec_zone *zone);
+
+/**
+ * Frees the given zone structure, and its rbtree of dnssec_names
+ * Individual ldns_rr RRs within those names are also freed
+ * \param[in] *zone the zone to free
+ */ 
+void ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone);
+
+/**
+ * Adds the given RR to the zone.
+ * It find whether there is a dnssec_name with that name present.
+ * If so, add it to that, if not create a new one. 
+ * Special handling of NSEC and RRSIG provided
+ *
+ * \param[in] zone the zone to add the RR to
+ * \param[in] rr The RR to add
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone,
+							 ldns_rr *rr);
+
+/**
+ * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
+ *
+ * \param[in] out the file descriptor to print the names to
+ * \param[in] tree the tree of ldns_dnssec_name structures to print
+ * \param[in] print_soa if true, print SOA records, if false, skip them
+ */
+void ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa);
+
+/**
+ * Prints the rbtree of ldns_dnssec_name structures to the file descriptor
+ *
+ * \param[in] out the file descriptor to print the names to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] tree the tree of ldns_dnssec_name structures to print
+ * \param[in] print_soa if true, print SOA records, if false, skip them
+ */
+void ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
+		ldns_rbtree_t *tree, bool print_soa);
+
+/**
+ * Prints the complete zone to the given file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] zone the dnssec_zone to print
+ */
+void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone);
+
+/**
+ * Prints the complete zone to the given file descriptor
+ *
+ * \param[in] out the file descriptor to print to
+ * \param[in] fmt the format of the textual representation
+ * \param[in] zone the dnssec_zone to print
+ */
+void ldns_dnssec_zone_print_fmt(FILE *out, 
+		const ldns_output_format *fmt, ldns_dnssec_zone *zone);
+
+/**
+ * Adds explicit dnssec_name structures for the empty nonterminals
+ * in this zone. (this is needed for NSEC3 generation)
+ *
+ * \param[in] zone the zone to check for empty nonterminals
+ * return LDNS_STATUS_OK on success.
+ */
+ldns_status ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone);
+
+/**
+ * If a NSEC3PARAM is available in the apex, walks the zone and returns true
+ * on the first optout nsec3.
+ *
+ * \param[in] zone the zone to check for nsec3 optout records
+ * return true when the zone has at least one nsec3 optout record.
+ */
+bool ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ldns/include/ldns/duration.h b/ldns/include/ldns/duration.h
new file mode 100644
index 0000000..f12edc4
--- /dev/null
+++ b/ldns/include/ldns/duration.h
@@ -0,0 +1,109 @@
+/*
+ * $Id: duration.h 4341 2011-01-31 15:21:09Z matthijs $
+ *
+ * Copyright (c) 2009 NLNet Labs. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ *
+ * This file is copied from the OpenDNSSEC source repository
+ * and only slightly adapted to make it fit.
+ */
+
+/**
+ *
+ * Durations.
+ */
+
+#ifndef LDNS_DURATION_H
+#define LDNS_DURATION_H
+
+#include <stdint.h>
+#include <time.h>
+
+/**
+ * Duration.
+ *
+ */
+typedef struct ldns_duration_struct ldns_duration_type;
+struct ldns_duration_struct
+{
+    time_t years;
+    time_t months;
+    time_t weeks;
+    time_t days;
+    time_t hours;
+    time_t minutes;
+    time_t seconds;
+};
+
+/**
+ * Create a new 'instant' duration.
+ * \return ldns_duration_type* created duration
+ *
+ */
+ldns_duration_type* ldns_duration_create(void);
+
+/**
+ * Compare durations.
+ * \param[in] d1 one duration
+ * \param[in] d2 another duration
+ * \return int 0 if equal, -1 if d1 < d2, 1 if d2 < d1
+ *
+ */
+int ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2);
+
+/**
+ * Create a duration from string.
+ * \param[in] str string-format duration
+ * \return ldns_duration_type* created duration
+ *
+ */
+ldns_duration_type* ldns_duration_create_from_string(const char* str);
+
+/**
+ * Convert a duration to a string.
+ * \param[in] duration duration to be converted
+ * \return char* string-format duration
+ *
+ */
+char* ldns_duration2string(ldns_duration_type* duration);
+
+/**
+ * Convert a duration to a time.
+ * \param[in] duration duration to be converted
+ * \return time_t time-format duration
+ *
+ */
+time_t ldns_duration2time(ldns_duration_type* duration);
+
+/**
+ * Clean up duration.
+ * \param[in] duration duration to be cleaned up
+ *
+ */
+void ldns_duration_cleanup(ldns_duration_type* duration);
+
+#endif /* LDNS_DURATION_H */
diff --git a/ldns/include/ldns/error.h b/ldns/include/ldns/error.h
new file mode 100644
index 0000000..cc11958
--- /dev/null
+++ b/ldns/include/ldns/error.h
@@ -0,0 +1,147 @@
+/**
+ * \file error.h
+ *
+ * Defines error numbers and functions to translate those to a readable string.
+ *
+ */
+ 
+/**
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#ifndef LDNS_ERROR_H
+#define LDNS_ERROR_H
+
+#include <ldns/util.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum ldns_enum_status {
+	LDNS_STATUS_OK,	
+	LDNS_STATUS_EMPTY_LABEL,
+	LDNS_STATUS_LABEL_OVERFLOW,
+	LDNS_STATUS_DOMAINNAME_OVERFLOW,
+	LDNS_STATUS_DOMAINNAME_UNDERFLOW,
+	LDNS_STATUS_DDD_OVERFLOW,
+	LDNS_STATUS_PACKET_OVERFLOW,
+	LDNS_STATUS_INVALID_POINTER,
+	LDNS_STATUS_MEM_ERR,
+	LDNS_STATUS_INTERNAL_ERR,
+	LDNS_STATUS_SSL_ERR,
+	LDNS_STATUS_ERR,
+	LDNS_STATUS_INVALID_INT,
+	LDNS_STATUS_INVALID_IP4,
+	LDNS_STATUS_INVALID_IP6,
+	LDNS_STATUS_INVALID_STR,
+	LDNS_STATUS_INVALID_B32_EXT,
+	LDNS_STATUS_INVALID_B64,
+	LDNS_STATUS_INVALID_HEX,
+	LDNS_STATUS_INVALID_TIME,
+	LDNS_STATUS_NETWORK_ERR,
+	LDNS_STATUS_ADDRESS_ERR,
+	LDNS_STATUS_FILE_ERR,
+	LDNS_STATUS_UNKNOWN_INET,
+	LDNS_STATUS_NOT_IMPL,
+	LDNS_STATUS_NULL,
+	LDNS_STATUS_CRYPTO_UNKNOWN_ALGO, 
+	LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL, 	
+	LDNS_STATUS_CRYPTO_NO_RRSIG,
+	LDNS_STATUS_CRYPTO_NO_DNSKEY,
+	LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY,
+	LDNS_STATUS_CRYPTO_NO_DS,
+	LDNS_STATUS_CRYPTO_NO_TRUSTED_DS,
+	LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY,
+	LDNS_STATUS_CRYPTO_VALIDATED,
+	LDNS_STATUS_CRYPTO_BOGUS,
+	LDNS_STATUS_CRYPTO_SIG_EXPIRED,
+	LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED,
+	LDNS_STATUS_CRYPTO_TSIG_BOGUS,
+	LDNS_STATUS_CRYPTO_TSIG_ERR,
+	LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION,
+	LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR,
+	LDNS_STATUS_ENGINE_KEY_NOT_LOADED,
+	LDNS_STATUS_NSEC3_ERR,
+	LDNS_STATUS_RES_NO_NS,
+	LDNS_STATUS_RES_QUERY,
+	LDNS_STATUS_WIRE_INCOMPLETE_HEADER,
+	LDNS_STATUS_WIRE_INCOMPLETE_QUESTION,
+	LDNS_STATUS_WIRE_INCOMPLETE_ANSWER,
+	LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY,
+	LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL,
+	LDNS_STATUS_NO_DATA,
+	LDNS_STATUS_CERT_BAD_ALGORITHM,
+	LDNS_STATUS_SYNTAX_TYPE_ERR,
+	LDNS_STATUS_SYNTAX_CLASS_ERR,
+	LDNS_STATUS_SYNTAX_TTL_ERR,
+	LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL,
+	LDNS_STATUS_SYNTAX_RDATA_ERR,
+	LDNS_STATUS_SYNTAX_DNAME_ERR,
+	LDNS_STATUS_SYNTAX_VERSION_ERR,
+	LDNS_STATUS_SYNTAX_ALG_ERR,
+	LDNS_STATUS_SYNTAX_KEYWORD_ERR,
+	LDNS_STATUS_SYNTAX_TTL,
+	LDNS_STATUS_SYNTAX_ORIGIN,
+	LDNS_STATUS_SYNTAX_INCLUDE,
+	LDNS_STATUS_SYNTAX_EMPTY,
+	LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW,
+	LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR,
+	LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW,
+	LDNS_STATUS_SYNTAX_BAD_ESCAPE,
+	LDNS_STATUS_SOCKET_ERROR,
+	LDNS_STATUS_SYNTAX_ERR,
+	LDNS_STATUS_DNSSEC_EXISTENCE_DENIED,
+	LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED,
+	LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED,
+	LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND,
+	LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG,
+	LDNS_STATUS_MISSING_RDATA_FIELDS_KEY,
+	LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN,
+	LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN,
+	LDNS_STATUS_DANE_STATUS_MESSAGES,
+	LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE,
+	LDNS_STATUS_DANE_UNKNOWN_SELECTOR,
+	LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE,
+	LDNS_STATUS_DANE_UNKNOWN_PROTOCOL,
+	LDNS_STATUS_DANE_UNKNOWN_TRANSPORT,
+	LDNS_STATUS_DANE_MISSING_EXTRA_CERTS,
+	LDNS_STATUS_DANE_EXTRA_CERTS_NOT_USED,
+	LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE,
+	LDNS_STATUS_DANE_INSECURE,
+	LDNS_STATUS_DANE_BOGUS,
+	LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
+	LDNS_STATUS_DANE_NON_CA_CERTIFICATE,
+	LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE,
+	LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR,
+	LDNS_STATUS_EXISTS_ERR,
+	LDNS_STATUS_INVALID_ILNP64,
+	LDNS_STATUS_INVALID_EUI48,
+	LDNS_STATUS_INVALID_EUI64,
+	LDNS_STATUS_WIRE_RDATA_ERR,
+	LDNS_STATUS_INVALID_TAG,
+	LDNS_STATUS_TYPE_NOT_IN_BITMAP,
+	LDNS_STATUS_INVALID_RDF_TYPE,
+	LDNS_STATUS_RDATA_OVERFLOW
+};
+typedef enum ldns_enum_status ldns_status;
+
+extern ldns_lookup_table ldns_error_str[];
+
+/**
+ * look up a descriptive text by each error. This function
+ * could use a better name
+ * \param[in] err ldns_status number
+ * \return the string for that error
+ */
+const char *ldns_get_errorstr_by_id(ldns_status err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_ERROR_H */
diff --git a/ldns/include/ldns/higher.h b/ldns/include/ldns/higher.h
new file mode 100644
index 0000000..597e134
--- /dev/null
+++ b/ldns/include/ldns/higher.h
@@ -0,0 +1,113 @@
+/**
+ * \file higher.h
+ *
+ * Specifies some higher level functions that could
+ * be useful for certain applications
+ */
+
+/*
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#ifndef LDNS_HIGHER_H
+#define LDNS_HIGHER_H
+
+#include <ldns/resolver.h>
+#include <ldns/rdata.h>
+#include <ldns/rr.h>
+#include <ldns/host2str.h>
+#include <ldns/tsig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Ask the resolver about name
+ * and return all address records
+ * \param[in] r the resolver to use
+ * \param[in] name the name to look for
+ * \param[in] c the class to use
+ * \param[in] flags give some optional flags to the query
+ */
+ldns_rr_list *ldns_get_rr_list_addr_by_name(ldns_resolver *r, ldns_rdf *name, ldns_rr_class c, uint16_t flags);
+
+/**
+ * ask the resolver about the address
+ * and return the name
+ * \param[in] r the resolver to use
+ * \param[in] addr the addr to look for
+ * \param[in] c the class to use
+ * \param[in] flags give some optional flags to the query
+ */
+ldns_rr_list *ldns_get_rr_list_name_by_addr(ldns_resolver *r, ldns_rdf *addr, ldns_rr_class c, uint16_t flags);
+
+/**
+ * wade through fp (a /etc/hosts like file)
+ * and return a rr_list containing all the 
+ * defined hosts in there
+ * \param[in] fp the file pointer to use
+ * \return ldns_rr_list * with the names
+ */
+ldns_rr_list *ldns_get_rr_list_hosts_frm_fp(FILE *fp);
+
+/**
+ * wade through fp (a /etc/hosts like file)
+ * and return a rr_list containing all the 
+ * defined hosts in there
+ * \param[in] fp the file pointer to use
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return ldns_rr_list * with the names
+ */
+ldns_rr_list *ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr);
+
+/**
+ * wade through fp (a /etc/hosts like file)
+ * and return a rr_list containing all the 
+ * defined hosts in there
+ * \param[in] filename the filename to use (NULL for /etc/hosts)
+ * \return ldns_rr_list * with the names
+ */
+ldns_rr_list *ldns_get_rr_list_hosts_frm_file(char *filename);
+
+/**
+ * This function is a wrapper function for ldns_get_rr_list_name_by_addr
+ * and ldns_get_rr_list_addr_by_name. It's name is from the getaddrinfo() 
+ * library call. It tries to mimic that call, but without the lowlevel
+ * stuff.
+ * \param[in] res The resolver. If this value is NULL then a resolver will
+ * be created by ldns_getaddrinfo.
+ * \param[in] node the name or ip address to look up
+ * \param[in] c the class to look in
+ * \param[out] list put the found RR's in this list
+ * \return the number of RR found.
+ */
+uint16_t ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c, ldns_rr_list **list);
+
+/**
+ * Check if t is enumerated in the nsec type rdata
+ * \param[in] nsec the NSEC Record to look in
+ * \param[in] t the type to check for
+ * \return true when t is found, otherwise return false
+ */
+bool ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t);
+
+/**
+ * Print a number of rdf's of the RR. The rdfnum-list must 
+ * be ended by -1, otherwise unpredictable things might happen.
+ * rdfs may be printed multiple times
+ * \param[in] fp FILE * to write to
+ * \param[in] r RR to write
+ * \param[in] rdfnum a list of rdf to print.
+ */
+void ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_HIGHER_H */
diff --git a/ldns/include/ldns/host2str.h b/ldns/include/ldns/host2str.h
new file mode 100644
index 0000000..e69389e
--- /dev/null
+++ b/ldns/include/ldns/host2str.h
@@ -0,0 +1,891 @@
+/**
+ * host2str.h -  txt presentation of RRs
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file
+ *
+ * Contains functions to translate the main structures to their text
+ * representation, as well as functions to print them.
+ */
+
+#ifndef LDNS_HOST2STR_H
+#define LDNS_HOST2STR_H
+
+#include <ldns/common.h>
+#include <ldns/error.h>
+#include <ldns/rr.h>
+#include <ldns/rdata.h>
+#include <ldns/packet.h>
+#include <ldns/buffer.h>
+#include <ldns/resolver.h>
+#include <ldns/zone.h>
+#include <ctype.h>
+
+#include "ldns/util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LDNS_APL_IP4            1
+#define LDNS_APL_IP6            2
+#define LDNS_APL_MASK           0x7f
+#define LDNS_APL_NEGATION       0x80
+
+/** 
+ * Represent a NULL pointer (instead of a pointer to a ldns_rr as "; (null)" 
+ * as opposed to outputting nothing at all in such a case.
+ */
+/*	Flag Name			Flag Nr.	Has data associated
+	---------------------------------------------------------------------*/
+#define LDNS_COMMENT_NULLS		(1 <<  0)
+/** Show key id with DNSKEY RR's as comment */
+#define LDNS_COMMENT_KEY_ID		(1 <<  1)
+/** Show if a DNSKEY is a ZSK or KSK as comment */
+#define LDNS_COMMENT_KEY_TYPE		(1 <<  2)
+/** Show DNSKEY key size as comment */
+#define LDNS_COMMENT_KEY_SIZE		(1 <<  3)
+/** Provide bubblebabble representation for DS RR's as comment */
+#define LDNS_COMMENT_BUBBLEBABBLE	(1 <<  4)
+/** Show when a NSEC3 RR has the optout flag set as comment */
+#define LDNS_COMMENT_FLAGS		(1 <<  5)
+/** Show the unhashed owner and next owner names for NSEC3 RR's as comment */
+#define LDNS_COMMENT_NSEC3_CHAIN	(1 <<  6)	/* yes */
+/** Print mark up */
+#define LDNS_COMMENT_LAYOUT		(1 <<  7)
+/** Also comment KEY_ID with RRSIGS **/
+#define LDNS_COMMENT_RRSIGS		(1 <<  8)
+#define LDNS_FMT_ZEROIZE_RRSIGS		(1 <<  9)
+#define LDNS_FMT_PAD_SOA_SERIAL		(1 << 10)
+#define LDNS_FMT_RFC3597		(1 << 11)	/* yes */
+
+#define LDNS_FMT_FLAGS_WITH_DATA			    2
+
+/** Show key id, type and size as comment for DNSKEY RR's */
+#define LDNS_COMMENT_KEY		(LDNS_COMMENT_KEY_ID  \
+					|LDNS_COMMENT_KEY_TYPE\
+					|LDNS_COMMENT_KEY_SIZE)
+
+/**
+ * Output format specifier
+ *
+ * Determines how Packets, Resource Records and Resource record data fiels are
+ * formatted when printing or converting to string.
+ * Currently it is only used to specify what aspects of a Resource Record are
+ * annotated in the comment section of the textual representation the record.
+ * This is speciefed with flags and potential exra data (such as for example
+ * a lookup map of hashes to real names for annotation NSEC3 records).
+ */
+struct ldns_struct_output_format
+{
+	/** Specification of how RR's should be formatted in text */
+	int   flags;
+	/** Potential extra data to be used with formatting RR's in text */
+	void *data;
+};
+typedef struct ldns_struct_output_format ldns_output_format;
+
+/**
+ * Output format struct with additional data for flags that use them.
+ * This struct may not be initialized directly. Use ldns_output_format_init
+ * to initialize.
+ */
+struct ldns_struct_output_format_storage
+{	int   flags;
+	ldns_rbtree_t* hashmap;    /* for LDNS_COMMENT_NSEC3_CHAIN */
+	ldns_rdf*      bitmap;     /* for LDNS_FMT_RFC3597     */
+};
+typedef struct ldns_struct_output_format_storage ldns_output_format_storage;
+
+/**
+ * Standard output format record that disables commenting in the textual 
+ * representation of Resource Records completely.
+ */
+extern const ldns_output_format *ldns_output_format_nocomments;
+/**
+ * Standard output format record that annotated only DNSKEY RR's with commenti
+ * text.
+ */
+extern const ldns_output_format *ldns_output_format_onlykeyids;
+/**
+ * The default output format record. Same as ldns_output_format_onlykeyids.
+ */
+extern const ldns_output_format *ldns_output_format_default;
+/**
+ * Standard output format record that shows all DNSKEY related information in
+ * the comment text, plus the optout flag when set with NSEC3's, plus the
+ * bubblebabble representation of DS RR's.
+ */
+extern const ldns_output_format *ldns_output_format_bubblebabble;
+
+/**
+ * Initialize output format storage to the default value.
+ * \param[in] fmt A reference to an output_format_ storage struct
+ * \return The initialized storage struct typecasted to ldns_output_format
+ */
+INLINE
+ldns_output_format* ldns_output_format_init(ldns_output_format_storage* fmt) {
+	fmt->flags   = ldns_output_format_default->flags;
+	fmt->hashmap = NULL;
+	fmt->bitmap  = NULL;
+	return (ldns_output_format*)fmt;
+}
+
+/**
+ * Set an ouput format flag.
+ */
+INLINE void ldns_output_format_set(ldns_output_format* fmt, int flag) {
+        fmt->flags |= flag;
+}
+
+/**
+ * Clear an ouput format flag.
+ */
+INLINE void ldns_output_format_clear(ldns_output_format* fmt, int flag) {
+        fmt->flags &= !flag;
+}
+
+/**
+ * Makes sure the LDNS_FMT_RFC3597 is set in the output format.
+ * Marks the type to be printed in RFC3597 format.
+ * /param[in] fmt the output format to update
+ * /param[in] the type to be printed in RFC3597 format
+ * /return LDNS_STATUS_OK on success
+ */
+ldns_status
+ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type type);
+
+/**
+ * Makes sure the LDNS_FMT_RFC3597 is set in the output format.
+ * Marks the type to not be printed in RFC3597 format. When no other types
+ * have been marked before, all known types (except the given one) will be
+ * marked for printing in RFC3597 format.
+ * /param[in] fmt the output format to update
+ * /param[in] the type not to be printed in RFC3597 format
+ * /return LDNS_STATUS_OK on success
+ */
+ldns_status
+ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type type);
+
+/**
+ * Converts an ldns packet opcode value to its mnemonic, and adds that
+ * to the output buffer
+ * \param[in] *output the buffer to add the data to
+ * \param[in] opcode to find the string representation of
+ * \return LDNS_STATUS_OK on success, or a buffer failure mode on error
+ */
+ldns_status
+ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode);
+
+/**
+ * Converts an ldns packet rcode value to its mnemonic, and adds that
+ * to the output buffer
+ * \param[in] *output the buffer to add the data to
+ * \param[in] rcode to find the string representation of
+ * \return LDNS_STATUS_OK on success, or a buffer failure mode on error
+ */
+ldns_status
+ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode);
+
+/**
+ * Converts an ldns algorithm type to its mnemonic, and adds that
+ * to the output buffer
+ * \param[in] *output the buffer to add the data to
+ * \param[in] algorithm to find the string representation of
+ * \return LDNS_STATUS_OK on success, or a buffer failure mode on error
+ */
+ldns_status
+ldns_algorithm2buffer_str(ldns_buffer *output,
+                          ldns_algorithm algorithm);
+
+/**
+ * Converts an ldns certificate algorithm type to its mnemonic, 
+ * and adds that to the output buffer
+ * \param[in] *output the buffer to add the data to
+ * \param[in] cert_algorithm to find the string representation of
+ * \return LDNS_STATUS_OK on success, or a buffer failure mode on error
+ */
+ldns_status
+ldns_cert_algorithm2buffer_str(ldns_buffer *output,
+                               ldns_cert_algorithm cert_algorithm);
+
+
+/**
+ * Converts a packet opcode to its mnemonic and returns that as
+ * an allocated null-terminated string.
+ * Remember to free it.
+ *
+ * \param[in] opcode the opcode to convert to text
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_pkt_opcode2str(ldns_pkt_opcode opcode);
+
+/**
+ * Converts a packet rcode to its mnemonic and returns that as
+ * an allocated null-terminated string.
+ * Remember to free it.
+ *
+ * \param[in] rcode the rcode to convert to text
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_pkt_rcode2str(ldns_pkt_rcode rcode);
+
+/**
+ * Converts a signing algorithms to its mnemonic and returns that as
+ * an allocated null-terminated string.
+ * Remember to free it.
+ *
+ * \param[in] algorithm the algorithm to convert to text
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_pkt_algorithm2str(ldns_algorithm algorithm);
+
+/**
+ * Converts a cert algorithm to its mnemonic and returns that as
+ * an allocated null-terminated string.
+ * Remember to free it.
+ *
+ * \param[in] cert_algorithm to convert to text
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_A rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_AAAA rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_STR rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_B64 rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_B32_EXT rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_HEX rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_TYPE rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_CLASS rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_ALG rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Converts an ldns_rr_type value to its string representation,
+ * and places it in the given buffer
+ * \param[in] *output The buffer to add the data to
+ * \param[in] type the ldns_rr_type to convert
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rr_type2buffer_str(ldns_buffer *output,
+                                    const ldns_rr_type type);
+
+/**
+ * Converts an ldns_rr_type value to its string representation,
+ * and returns that string. For unknown types, the string
+ * "TYPE<id>" is returned. This function allocates data that must be
+ * freed by the caller
+ * \param[in] type the ldns_rr_type to convert
+ * \return a newly allocated string
+ */
+char *ldns_rr_type2str(const ldns_rr_type type);
+
+/**
+ * Converts an ldns_rr_class value to its string representation,
+ * and places it in the given buffer
+ * \param[in] *output The buffer to add the data to
+ * \param[in] klass the ldns_rr_class to convert
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rr_class2buffer_str(ldns_buffer *output,
+                                     const ldns_rr_class klass);
+
+/**
+ * Converts an ldns_rr_class value to its string representation,
+ * and returns that string. For unknown types, the string
+ * "CLASS<id>" is returned. This function allocates data that must be
+ * freed by the caller
+ * \param[in] klass the ldns_rr_class to convert
+ * \return a newly allocated string
+ */
+char *ldns_rr_class2str(const ldns_rr_class klass);
+
+
+/** 
+ * Converts an LDNS_RDF_TYPE_CERT rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_LOC rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_UNKNOWN rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_NSAP rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_ATMA rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_WKS rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_NSEC rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_PERIOD rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_TSIGTIME rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_tsigtime(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_APL rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_INT16_DATA rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_IPSECKEY rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Converts the data in the rdata field to presentation
+ * format (as char *) and appends it to the given buffer
+ *
+ * \param[in] output pointer to the buffer to append the data to
+ * \param[in] rdf the pointer to the rdafa field containing the data
+ * \return status
+ */
+ldns_status ldns_rdf2buffer_str(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Converts the data in the resource record to presentation
+ * format (as char *) and appends it to the given buffer.
+ * The presentation format of DNSKEY record is annotated with comments giving
+ * the id, type and size of the key.
+ *
+ * \param[in] output pointer to the buffer to append the data to
+ * \param[in] rr the pointer to the rr field to convert
+ * \return status
+ */
+ldns_status ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr);
+
+/**
+ * Converts the data in the resource record to presentation
+ * format (as char *) and appends it to the given buffer.
+ * The presentation format is annotated with comments giving
+ * additional information on the record.
+ *
+ * \param[in] output pointer to the buffer to append the data to
+ * \param[in] fmt how to format the textual representation of the 
+ *            resource record.
+ * \param[in] rr the pointer to the rr field to convert
+ * \return status
+ */
+ldns_status ldns_rr2buffer_str_fmt(ldns_buffer *output, 
+		const ldns_output_format *fmt, const ldns_rr *rr);
+
+/**
+ * Converts the data in the DNS packet to presentation
+ * format (as char *) and appends it to the given buffer
+ *
+ * \param[in] output pointer to the buffer to append the data to
+ * \param[in] pkt the pointer to the packet to convert
+ * \return status
+ */
+ldns_status ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
+
+/**
+ * Converts the data in the DNS packet to presentation
+ * format (as char *) and appends it to the given buffer
+ *
+ * \param[in] output pointer to the buffer to append the data to
+ * \param[in] fmt how to format the textual representation of the packet
+ * \param[in] pkt the pointer to the packet to convert
+ * \return status
+ */
+ldns_status ldns_pkt2buffer_str_fmt(ldns_buffer *output,
+		const ldns_output_format *fmt, const ldns_pkt *pkt);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_NSEC3_SALT rdata element to string format and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf);
+
+
+/**
+ * Converts the data in the DNS packet to presentation
+ * format (as char *) and appends it to the given buffer
+ *
+ * \param[in] output pointer to the buffer to append the data to
+ * \param[in] k the pointer to the private key to convert
+ * \return status
+ */
+ldns_status ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k);
+
+/**
+ * Converts an LDNS_RDF_TYPE_INT8 rdata element to string format and adds it to the output buffer
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Converts an LDNS_RDF_TYPE_INT16 rdata element to string format and adds it to the output buffer
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Converts an LDNS_RDF_TYPE_INT32 rdata element to string format and adds it to the output buffer
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Converts an LDNS_RDF_TYPE_TIME rdata element to string format and adds it to the output buffer
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_ILNP64 rdata element to 4 hexadecimal numbers
+ * separated by colons and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_ilnp64(ldns_buffer *output,
+		const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_EUI48 rdata element to 6 hexadecimal numbers
+ * separated by dashes and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_eui48(ldns_buffer *output,
+		const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_EUI64 rdata element to 8 hexadecimal numbers
+ * separated by dashes and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_eui64(ldns_buffer *output,
+		const ldns_rdf *rdf);
+
+/** 
+ * Adds the LDNS_RDF_TYPE_TAG rdata to the output buffer,
+ * provided it contains only alphanumeric characters.
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_tag(ldns_buffer *output,
+		const ldns_rdf *rdf);
+
+/** 
+ * Adds the LDNS_RDF_TYPE_LONG_STR rdata to the output buffer, in-between 
+ * double quotes and all non printable characters properly escaped.
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_long_str(ldns_buffer *output,
+	       	const ldns_rdf *rdf);
+
+/** 
+ * Converts an LDNS_RDF_TYPE_HIP rdata element to presentation format for
+ * the algorithm, HIT and Public Key and adds it the output buffer .
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_hip(ldns_buffer *output,
+		const ldns_rdf *rdf);
+
+/**
+ * Converts the data in the rdata field to presentation format and
+ * returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] rdf The rdata field to convert
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_rdf2str(const ldns_rdf *rdf);
+
+/**
+ * Converts the data in the resource record to presentation format and
+ * returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] rr The rdata field to convert
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_rr2str(const ldns_rr *rr);
+
+/**
+ * Converts the data in the resource record to presentation format and
+ * returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] fmt how to format the resource record
+ * \param[in] rr The rdata field to convert
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr);
+
+/**
+ * Converts the data in the DNS packet to presentation format and
+ * returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] pkt The rdata field to convert
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_pkt2str(const ldns_pkt *pkt);
+
+/**
+ * Converts the data in the DNS packet to presentation format and
+ * returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] fmt how to format the packet
+ * \param[in] pkt The rdata field to convert
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt);
+
+/**
+ * Converts a private key to the test presentation fmt and
+ * returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] k the key to convert to text
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_key2str(const ldns_key *k);
+
+/**
+ * Converts a list of resource records to presentation format
+ * and returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] rr_list the rr_list to convert to text
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_rr_list2str(const ldns_rr_list *rr_list);
+
+/**
+ * Converts a list of resource records to presentation format
+ * and returns that as a char *.
+ * Remember to free it.
+ *
+ * \param[in] fmt how to format the list of resource records
+ * \param[in] rr_list the rr_list to convert to text
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_rr_list2str_fmt(
+		const ldns_output_format *fmt, const ldns_rr_list *rr_list);
+
+/**
+ * Returns a copy of the data in the buffer as a null terminated
+ * char * string. The returned string must be freed by the caller.
+ * The buffer must be in write modus and may thus not have been flipped.
+ *
+ * \param[in] buffer buffer containing char * data
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_buffer2str(ldns_buffer *buffer);
+
+/**
+ * Exports and returns the data in the buffer as a null terminated
+ * char * string. The returned string must be freed by the caller.
+ * The buffer must be in write modus and may thus not have been flipped.
+ * The buffer is fixed after this function returns.
+ *
+ * \param[in] buffer buffer containing char * data
+ * \return null terminated char * data, or NULL on error
+ */
+char *ldns_buffer_export2str(ldns_buffer *buffer);
+
+/**
+ * Prints the data in the rdata field to the given file stream
+ * (in presentation format)
+ *
+ * \param[in] output the file stream to print to
+ * \param[in] rdf the rdata field to print
+ * \return void
+ */
+void ldns_rdf_print(FILE *output, const ldns_rdf *rdf);
+
+/**
+ * Prints the data in the resource record to the given file stream
+ * (in presentation format)
+ *
+ * \param[in] output the file stream to print to
+ * \param[in] rr the resource record to print
+ * \return void
+ */
+void ldns_rr_print(FILE *output, const ldns_rr *rr);
+
+/**
+ * Prints the data in the resource record to the given file stream
+ * (in presentation format)
+ *
+ * \param[in] output the file stream to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] rr the resource record to print
+ * \return void
+ */
+void ldns_rr_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_rr *rr);
+
+/**
+ * Prints the data in the DNS packet to the given file stream
+ * (in presentation format)
+ *
+ * \param[in] output the file stream to print to
+ * \param[in] pkt the packet to print
+ * \return void
+ */
+void ldns_pkt_print(FILE *output, const ldns_pkt *pkt);
+
+/**
+ * Prints the data in the DNS packet to the given file stream
+ * (in presentation format)
+ *
+ * \param[in] output the file stream to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] pkt the packet to print
+ * \return void
+ */
+void ldns_pkt_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_pkt *pkt);
+
+/**
+ * Converts a rr_list to presentation format and appends it to
+ * the output buffer
+ * \param[in] output the buffer to append output to
+ * \param[in] list the ldns_rr_list to print
+ * \return ldns_status
+ */
+ldns_status ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list);
+
+/**
+ * Converts a rr_list to presentation format and appends it to
+ * the output buffer
+ * \param[in] output the buffer to append output to
+ * \param[in] fmt format of the textual representation
+ * \param[in] list the ldns_rr_list to print
+ * \return ldns_status
+ */
+ldns_status ldns_rr_list2buffer_str_fmt(ldns_buffer *output, 
+		const ldns_output_format *fmt, const ldns_rr_list *list);
+
+/**
+ * Converts the header of a packet to presentation format and appends it to
+ * the output buffer
+ * \param[in] output the buffer to append output to
+ * \param[in] pkt the packet to convert the header of
+ * \return ldns_status
+ */
+ldns_status ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt);
+
+/**
+ * print a rr_list to output
+ * \param[in] output the fd to print to
+ * \param[in] list the rr_list to print
+ */
+void ldns_rr_list_print(FILE *output, const ldns_rr_list *list);
+
+/**
+ * print a rr_list to output
+ * \param[in] output the fd to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] list the rr_list to print
+ */
+void ldns_rr_list_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_rr_list *list);
+
+/**
+ * Print a resolver (in sofar that is possible) state
+ * to output.
+ * \param[in] output the fd to print to
+ * \param[in] r the resolver to print
+ */
+void ldns_resolver_print(FILE *output, const ldns_resolver *r);
+
+/**
+ * Print a resolver (in sofar that is possible) state
+ * to output.
+ * \param[in] output the fd to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] r the resolver to print
+ */
+void ldns_resolver_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_resolver *r);
+
+/**
+ * Print a zone structure * to output. Note the SOA record
+ * is included in this output
+ * \param[in] output the fd to print to
+ * \param[in] z the zone to print
+ */
+void ldns_zone_print(FILE *output, const ldns_zone *z);
+
+/**
+ * Print a zone structure * to output. Note the SOA record
+ * is included in this output
+ * \param[in] output the fd to print to
+ * \param[in] fmt format of the textual representation
+ * \param[in] z the zone to print
+ */
+void ldns_zone_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_zone *z);
+
+/**
+ * Print the ldns_rdf containing a dname to the buffer
+ * \param[in] output the buffer to print to
+ * \param[in] dname the dname to print
+ * \return ldns_status message if the printing succeeded
+ */
+ldns_status ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_HOST2STR_H */
diff --git a/ldns/include/ldns/host2wire.h b/ldns/include/ldns/host2wire.h
new file mode 100644
index 0000000..94693cd
--- /dev/null
+++ b/ldns/include/ldns/host2wire.h
@@ -0,0 +1,197 @@
+/*
+ * host2wire.h - 2wire conversion routines
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file
+ *
+ * Contains all functions to translate the main structures to wire format
+ */
+
+#ifndef LDNS_HOST2WIRE_H
+#define LDNS_HOST2WIRE_H
+
+#include <ldns/common.h>
+#include <ldns/error.h>
+#include <ldns/rr.h>
+#include <ldns/rdata.h>
+#include <ldns/packet.h>
+#include <ldns/buffer.h>
+#include <ctype.h>
+
+#include "ldns/util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Copies the dname data to the buffer in wire format
+ * \param[out] *buffer buffer to append the result to
+ * \param[in] *name rdata dname to convert
+ * \return ldns_status
+ */
+ldns_status ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name);
+
+/**
+ * Copies the dname data to the buffer in wire format
+ * \param[out] *buffer buffer to append the result to
+ * \param[in] *name rdata dname to convert
+ * \param[out] *compression_data data structure holding state for compression
+ * \return ldns_status
+ */
+ldns_status ldns_dname2buffer_wire_compress(ldns_buffer *buffer, const ldns_rdf *name, ldns_rbtree_t *compression_data);
+
+/**
+ * Copies the rdata data to the buffer in wire format
+ * \param[out] *output buffer to append the result to
+ * \param[in] *rdf rdata to convert
+ * \return ldns_status
+ */
+ldns_status ldns_rdf2buffer_wire(ldns_buffer *output, const ldns_rdf *rdf);
+
+/**
+ * Copies the rdata data to the buffer in wire format
+ * \param[out] *output buffer to append the result to
+ * \param[in] *rdf rdata to convert
+ * \param[out] *compression_data data structure holding state for compression
+ * \return ldns_status
+ */
+ldns_status ldns_rdf2buffer_wire_compress(ldns_buffer *output, const ldns_rdf *rdf, ldns_rbtree_t *compression_data);
+
+/**
+ * Copies the rdata data to the buffer in wire format
+ * If the rdata is a dname, the letters will be lowercased
+ * during the conversion
+ * \param[out] *output buffer to append the result to
+ * \param[in] *rdf rdata to convert
+ * \return ldns_status
+ */
+ldns_status ldns_rdf2buffer_wire_canonical(ldns_buffer *output,
+								   const ldns_rdf *rdf);
+
+/**
+ * Copies the rr data to the buffer in wire format
+ * \param[out] *output buffer to append the result to
+ * \param[in] *rr resource record to convert
+ * \param[in] section the section in the packet this rr is supposed to be in
+ *            (to determine whether to add rdata or not)
+ * \return ldns_status
+ */
+ldns_status ldns_rr2buffer_wire(ldns_buffer *output,
+						  const ldns_rr *rr,
+						  int section);
+
+/**
+ * Copies the rr data to the buffer in wire format while doing DNAME compression
+ * \param[out] *output buffer to append the result to
+ * \param[in] *rr resource record to convert
+ * \param[in] section the section in the packet this rr is supposed to be in
+ *            (to determine whether to add rdata or not)
+ * \param[out] *compression_data data structure holding state information for compression
+ * \return ldns_status
+ */
+ldns_status ldns_rr2buffer_wire_compress(ldns_buffer *output,
+						  const ldns_rr *rr,
+						  int section,
+						  ldns_rbtree_t *compression_data);
+
+/**
+ * Copies the rr data to the buffer in wire format, in canonical format
+ * according to RFC3597 (every dname in rdata fields of RR's mentioned in
+ * that RFC will be lowercased)
+ * \param[out] *output buffer to append the result to
+ * \param[in] *rr resource record to convert
+ * \param[in] section the section in the packet this rr is supposed to be in
+ *            (to determine whether to add rdata or not)
+ * \return ldns_status
+ */
+ldns_status ldns_rr2buffer_wire_canonical(ldns_buffer *output,
+								  const ldns_rr *rr,
+								  int section);
+
+
+/**
+ * Converts a rrsig to wireformat BUT EXCLUDE the rrsig rdata
+ * This is needed in DNSSEC verification
+ * \param[out] output buffer to append the result to
+ * \param[in] sigrr signature rr to operate on
+ * \return ldns_status
+ */
+ldns_status ldns_rrsig2buffer_wire(ldns_buffer *output, const ldns_rr *sigrr);
+
+/**
+ * Converts an rr's rdata to wireformat, while excluding
+ * the ownername and all the stuff before the rdata.
+ * This is needed in DNSSEC keytag calculation, the ds
+ * calcalution from the key and maybe elsewhere.
+ *
+ * \param[out] *output buffer where to put the result
+ * \param[in] *rr rr to operate on
+ * \return ldns_status
+ */
+ldns_status ldns_rr_rdata2buffer_wire(ldns_buffer *output, const ldns_rr *rr);
+
+/**
+ * Copies the packet data to the buffer in wire format
+ * \param[out] *output buffer to append the result to
+ * \param[in] *pkt packet to convert
+ * \return ldns_status
+ */
+ldns_status ldns_pkt2buffer_wire(ldns_buffer *output, const ldns_pkt *pkt);
+
+/**
+ * Copies the rr_list data to the buffer in wire format
+ * \param[out] *output buffer to append the result to
+ * \param[in] *rrlist rr_list to to convert
+ * \return ldns_status
+ */
+ldns_status ldns_rr_list2buffer_wire(ldns_buffer *output, const ldns_rr_list *rrlist);
+
+/**
+ * Allocates an array of uint8_t at dest, and puts the wireformat of the
+ * given rdf in that array. The result_size value contains the
+ * length of the array, if it succeeds, and 0 otherwise (in which case
+ * the function also returns NULL)
+ *
+ * \param[out] dest pointer to the array of bytes to be created
+ * \param[in] rdf the rdata field to convert
+ * \param[out] size the size of the converted result
+ */
+ldns_status ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *size);
+
+/**
+ * Allocates an array of uint8_t at dest, and puts the wireformat of the
+ * given rr in that array. The result_size value contains the
+ * length of the array, if it succeeds, and 0 otherwise (in which case
+ * the function also returns NULL)
+ *
+ * If the section argument is LDNS_SECTION_QUESTION, data like ttl and rdata
+ * are not put into the result
+ *
+ * \param[out] dest pointer to the array of bytes to be created
+ * \param[in] rr the rr to convert
+ * \param[in] section the rr section, determines how the rr is written.
+ * \param[out] size the size of the converted result
+ */
+ldns_status ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *size);
+
+/**
+ * Allocates an array of uint8_t at dest, and puts the wireformat of the
+ * given packet in that array. The result_size value contains the
+ * length of the array, if it succeeds, and 0 otherwise (in which case
+ * the function also returns NULL)
+ */
+ldns_status ldns_pkt2wire(uint8_t **dest, const ldns_pkt *p, size_t *size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_HOST2WIRE_H */
diff --git a/ldns/include/ldns/keys.h b/ldns/include/ldns/keys.h
new file mode 100644
index 0000000..d3b4873
--- /dev/null
+++ b/ldns/include/ldns/keys.h
@@ -0,0 +1,621 @@
+/*
+ * 
+ * keys.h
+ *
+ * priv key definitions
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file
+ *
+ * Addendum to \ref dnssec.h, this module contains key and algorithm definitions and functions.
+ */
+ 
+
+#ifndef LDNS_KEYS_H
+#define LDNS_KEYS_H
+
+#include <ldns/common.h>
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+#include <openssl/ssl.h>
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+#include <ldns/util.h>
+#include <errno.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern ldns_lookup_table ldns_signing_algorithms[];
+
+#define LDNS_KEY_ZONE_KEY 0x0100   /* rfc 4034 */
+#define LDNS_KEY_SEP_KEY 0x0001    /* rfc 4034 */
+#define LDNS_KEY_REVOKE_KEY 0x0080 /* rfc 5011 */
+
+/**
+ * Algorithms used in dns
+ */
+enum ldns_enum_algorithm
+{
+        LDNS_RSAMD5             = 1,   /* RFC 4034,4035 */
+        LDNS_DH                 = 2,
+        LDNS_DSA                = 3,
+        LDNS_ECC                = 4,
+        LDNS_RSASHA1            = 5,
+        LDNS_DSA_NSEC3          = 6,
+        LDNS_RSASHA1_NSEC3      = 7,
+        LDNS_RSASHA256          = 8,   /* RFC 5702 */
+        LDNS_RSASHA512          = 10,  /* RFC 5702 */
+        LDNS_ECC_GOST           = 12,  /* RFC 5933 */
+        LDNS_ECDSAP256SHA256    = 13,  /* RFC 6605 */
+        LDNS_ECDSAP384SHA384    = 14,  /* RFC 6605 */
+        LDNS_INDIRECT           = 252,
+        LDNS_PRIVATEDNS         = 253,
+        LDNS_PRIVATEOID         = 254
+};
+typedef enum ldns_enum_algorithm ldns_algorithm;
+
+/**
+ * Hashing algorithms used in the DS record
+ */
+enum ldns_enum_hash
+{
+        LDNS_SHA1               = 1,  /* RFC 4034 */
+        LDNS_SHA256             = 2,  /* RFC 4509 */
+        LDNS_HASH_GOST          = 3,  /* RFC 5933 */
+        LDNS_SHA384             = 4   /* RFC 6605 */
+};
+typedef enum ldns_enum_hash ldns_hash;
+
+/**
+ * Algorithms used in dns for signing
+ */
+enum ldns_enum_signing_algorithm
+{
+	LDNS_SIGN_RSAMD5	 = LDNS_RSAMD5,
+	LDNS_SIGN_RSASHA1	 = LDNS_RSASHA1,
+	LDNS_SIGN_DSA		 = LDNS_DSA,
+	LDNS_SIGN_RSASHA1_NSEC3  = LDNS_RSASHA1_NSEC3,
+	LDNS_SIGN_RSASHA256	 = LDNS_RSASHA256,
+	LDNS_SIGN_RSASHA512	 = LDNS_RSASHA512,
+	LDNS_SIGN_DSA_NSEC3	 = LDNS_DSA_NSEC3,
+	LDNS_SIGN_ECC_GOST       = LDNS_ECC_GOST,
+        LDNS_SIGN_ECDSAP256SHA256 = LDNS_ECDSAP256SHA256,
+        LDNS_SIGN_ECDSAP384SHA384 = LDNS_ECDSAP384SHA384,
+	LDNS_SIGN_HMACMD5	 = 157,	/* not official! This type is for TSIG, not DNSSEC */
+	LDNS_SIGN_HMACSHA1	 = 158,	/* not official! This type is for TSIG, not DNSSEC */
+	LDNS_SIGN_HMACSHA256 = 159  /* ditto */
+};
+typedef enum ldns_enum_signing_algorithm ldns_signing_algorithm;
+
+/**
+ * General key structure, can contain all types of keys that
+ * are used in DNSSEC. Mostly used to store private keys, since
+ * public keys can also be stored in a \ref ldns_rr with type
+ * \ref LDNS_RR_TYPE_DNSKEY.
+ *
+ * This structure can also store some variables that influence the
+ * signatures generated by signing with this key, for instance the
+ * inception date.
+ */
+struct ldns_struct_key {
+	ldns_signing_algorithm _alg;
+	/** Whether to use this key when signing */
+	bool _use;
+	/** Storage pointers for the types of keys supported */
+	/* TODO remove unions? */
+	struct {
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+#ifndef S_SPLINT_S
+		/* The key can be an OpenSSL EVP Key
+		 */
+		EVP_PKEY *key;
+#endif
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+		/**
+		 * The key can be an HMAC key
+		 */
+		struct {
+			unsigned char *key;
+			size_t size;
+		} hmac;
+		/** the key structure can also just point to some external
+		 *  key data
+		 */
+		void *external_key;
+	} _key;
+	/** Depending on the key we can have extra data */
+	union {
+                /** Some values that influence generated signatures */
+		struct {
+			/** The TTL of the rrset that is currently signed */
+			uint32_t orig_ttl;
+			/** The inception date of signatures made with this key. */
+			uint32_t inception;
+			/** The expiration date of signatures made with this key. */
+			uint32_t expiration;
+			/** The keytag of this key. */
+			uint16_t keytag;
+			/** The dnssec key flags as specified in RFC4035, like ZSK and KSK */
+			uint16_t flags;
+		}  dnssec;
+	} _extra;
+	/** Owner name of the key */
+	ldns_rdf *_pubkey_owner;
+};
+typedef struct ldns_struct_key ldns_key;
+
+/**
+ * Same as rr_list, but now for keys 
+ */
+struct ldns_struct_key_list
+{
+	size_t _key_count;
+	ldns_key **_keys;
+};
+typedef struct ldns_struct_key_list ldns_key_list;
+
+
+/**
+ * Creates a new empty key list
+ * \return a new ldns_key_list structure pointer
+ */
+ldns_key_list *ldns_key_list_new(void);
+
+/** 
+ * Creates a new empty key structure
+ * \return a new ldns_key * structure
+ */
+ldns_key *ldns_key_new(void);
+
+/**
+ * Creates a new key based on the algorithm
+ *
+ * \param[in] a The algorithm to use
+ * \param[in] size the number of bytes for the keysize
+ * \return a new ldns_key structure with the key
+ */
+ldns_key *ldns_key_new_frm_algorithm(ldns_signing_algorithm a, uint16_t size);
+
+/**
+ * Creates a new priv key based on the 
+ * contents of the file pointed by fp.
+ *
+ * The file should be in Private-key-format v1.x.
+ *
+ * \param[out] k the new ldns_key structure
+ * \param[in] fp the file pointer to use
+ * \return an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_key_new_frm_fp(ldns_key **k, FILE *fp);
+
+/**
+ * Creates a new private key based on the 
+ * contents of the file pointed by fp
+ *
+ * The file should be in Private-key-format v1.x.
+ *
+ * \param[out] k the new ldns_key structure
+ * \param[in] fp the file pointer to use
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_key_new_frm_fp_l(ldns_key **k, FILE *fp, int *line_nr);
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * Read the key with the given id from the given engine and store it
+ * in the given ldns_key structure. The algorithm type is set
+ */
+ldns_status ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm);
+
+
+/**
+ * frm_fp helper function. This function parses the
+ * remainder of the (RSA) priv. key file generated from bind9
+ * \param[in] fp the file to parse
+ * \return NULL on failure otherwise a RSA structure
+ */
+RSA *ldns_key_new_frm_fp_rsa(FILE *fp);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * frm_fp helper function. This function parses the
+ * remainder of the (RSA) priv. key file generated from bind9
+ * \param[in] fp the file to parse
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return NULL on failure otherwise a RSA structure
+ */
+RSA *ldns_key_new_frm_fp_rsa_l(FILE *fp, int *line_nr);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * frm_fp helper function. This function parses the
+ * remainder of the (DSA) priv. key file
+ * \param[in] fp the file to parse
+ * \return NULL on failure otherwise a RSA structure
+ */
+DSA *ldns_key_new_frm_fp_dsa(FILE *fp);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * frm_fp helper function. This function parses the
+ * remainder of the (DSA) priv. key file
+ * \param[in] fp the file to parse
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return NULL on failure otherwise a RSA structure
+ */
+DSA *ldns_key_new_frm_fp_dsa_l(FILE *fp, int *line_nr);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * frm_fp helper function. This function parses the
+ * remainder of the (HMAC-MD5) key file
+ * This function allocated a buffer that needs to be freed
+ * \param[in] fp the file to parse
+ * \param[out] hmac_size the number of bits in the resulting buffer
+ * \return NULL on failure otherwise a newly allocated char buffer
+ */
+unsigned char *ldns_key_new_frm_fp_hmac(FILE *fp, size_t *hmac_size);
+#endif
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * frm_fp helper function. This function parses the
+ * remainder of the (HMAC-MD5) key file
+ * This function allocated a buffer that needs to be freed
+ * \param[in] fp the file to parse
+ * \param[in] line_nr pointer to an integer containing the current line number (for error reporting purposes)
+ * \param[out] hmac_size the number of bits in the resulting buffer
+ * \return NULL on failure otherwise a newly allocated char buffer
+ */
+unsigned char *ldns_key_new_frm_fp_hmac_l(FILE *fp, int *line_nr, size_t *hmac_size);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+/* acces write functions */
+/**
+ * Set the key's algorithm
+ * \param[in] k the key
+ * \param[in] l the algorithm
+ */
+void ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l);
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * Set the key's evp key
+ * \param[in] k the key
+ * \param[in] e the evp key
+ */
+void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e);
+
+/**
+ * Set the key's rsa data.
+ * The rsa data should be freed by the user.
+ * \param[in] k the key
+ * \param[in] r the rsa data
+ */
+void ldns_key_set_rsa_key(ldns_key *k, RSA *r);
+
+/**
+ * Set the key's dsa data
+ * The dsa data should be freed by the user.
+ * \param[in] k the key
+ * \param[in] d the dsa data
+ */
+void ldns_key_set_dsa_key(ldns_key *k, DSA *d);
+
+/**
+ * Assign the key's rsa data
+ * The rsa data will be freed automatically when the key is freed.
+ * \param[in] k the key
+ * \param[in] r the rsa data
+ */
+void ldns_key_assign_rsa_key(ldns_key *k, RSA *r);
+
+/**
+ * Assign the key's dsa data
+ * The dsa data will be freed automatically when the key is freed.
+ * \param[in] k the key
+ * \param[in] d the dsa data
+ */
+void ldns_key_assign_dsa_key(ldns_key *k, DSA *d);
+
+/** 
+ * Get the PKEY id for GOST, loads GOST into openssl as a side effect.
+ * Only available if GOST is compiled into the library and openssl.
+ * \return the gost id for EVP_CTX creation.
+ */
+int ldns_key_EVP_load_gost_id(void);
+
+/** Release the engine reference held for the GOST engine. */
+void ldns_key_EVP_unload_gost(void);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+/**
+ * Set the key's hmac data
+ * \param[in] k the key
+ * \param[in] hmac the raw key data
+ */
+void ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac);
+
+/**
+ * Set the key id data. This is used if the key points to
+ * some externally stored key data
+ * 
+ * Only the pointer is set, the data there is not copied,
+ * and must be freed manually; ldns_key_deep_free() does 
+ * *not* free this data
+ * \param[in] key the key
+ * \param[in] external_key key id data
+ */
+void ldns_key_set_external_key(ldns_key *key, void *external_key);
+
+/**
+ * Set the key's hmac size
+ * \param[in] k the key
+ * \param[in] hmac_size the size of the hmac data
+ */
+void ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size);
+/**
+ * Set the key's original ttl
+ * \param[in] k the key
+ * \param[in] t the ttl
+ */
+void ldns_key_set_origttl(ldns_key *k, uint32_t t);
+/**
+ * Set the key's inception date (seconds after epoch)
+ * \param[in] k the key
+ * \param[in] i the inception
+ */
+void ldns_key_set_inception(ldns_key *k, uint32_t i);
+/**
+ * Set the key's expiration date (seconds after epoch)
+ * \param[in] k the key
+ * \param[in] e the expiration
+ */
+void ldns_key_set_expiration(ldns_key *k, uint32_t e);
+/**
+ * Set the key's pubkey owner
+ * \param[in] k the key
+ * \param[in] r the owner
+ */
+void ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r);
+/**
+ * Set the key's key tag
+ * \param[in] k the key
+ * \param[in] tag the keytag
+ */
+void ldns_key_set_keytag(ldns_key *k, uint16_t tag);
+/**
+ * Set the key's flags
+ * \param[in] k the key
+ * \param[in] flags the flags
+ */
+void ldns_key_set_flags(ldns_key *k, uint16_t flags);
+/**
+ * Set the keylist's key count to count
+ * \param[in] key the key
+ * \param[in] count the cuont
+ */
+void ldns_key_list_set_key_count(ldns_key_list *key, size_t count);
+
+/**     
+ * pushes a key to a keylist
+ * \param[in] key_list the key_list to push to 
+ * \param[in] key the key to push 
+ * \return false on error, otherwise true
+ */      
+bool ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key);
+
+/**
+ * returns the number of keys in the key list
+ * \param[in] key_list the key_list
+ * \return the numbers of keys in the list
+ */
+size_t ldns_key_list_key_count(const ldns_key_list *key_list);
+
+/**
+ * returns a pointer to the key in the list at the given position
+ * \param[in] key the key
+ * \param[in] nr the position in the list
+ * \return the key
+ */
+ldns_key *ldns_key_list_key(const ldns_key_list *key, size_t nr);
+
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+/**
+ * returns the (openssl) RSA struct contained in the key
+ * \param[in] k the key to look in
+ * \return the RSA * structure in the key
+ */
+RSA *ldns_key_rsa_key(const ldns_key *k);
+/**
+ * returns the (openssl) EVP struct contained in the key
+ * \param[in] k the key to look in
+ * \return the RSA * structure in the key
+ */
+EVP_PKEY *ldns_key_evp_key(const ldns_key *k);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+/**
+ * returns the (openssl) DSA struct contained in the key
+ */
+#if LDNS_BUILD_CONFIG_HAVE_SSL
+DSA *ldns_key_dsa_key(const ldns_key *k);
+#endif /* LDNS_BUILD_CONFIG_HAVE_SSL */
+
+/**
+ * return the signing alg of the key
+ * \param[in] k the key
+ * \return the algorithm
+ */
+ldns_signing_algorithm ldns_key_algorithm(const ldns_key *k);
+/**
+ * set the use flag
+ * \param[in] k the key
+ * \param[in] v the boolean value to set the _use field to
+ */
+void ldns_key_set_use(ldns_key *k, bool v);
+/**
+ * return the use flag
+ * \param[in] k the key
+ * \return the boolean value of the _use field
+ */
+bool ldns_key_use(const ldns_key *k);
+/**
+ * return the hmac key data
+ * \param[in] k the key
+ * \return the hmac key data
+ */
+unsigned char *ldns_key_hmac_key(const ldns_key *k);
+/**
+ * return the key id key data
+ * \param[in] k the key
+ * \return the key id data
+ */
+void *ldns_key_external_key(const ldns_key *k);
+/**
+ * return the hmac key size
+ * \param[in] k the key
+ * \return the hmac key size
+ */
+size_t ldns_key_hmac_size(const ldns_key *k);
+/**
+ * return the original ttl of the key
+ * \param[in] k the key
+ * \return the original ttl
+ */
+uint32_t ldns_key_origttl(const ldns_key *k);
+/**
+ * return the key's inception date
+ * \param[in] k the key
+ * \return the inception date
+ */
+uint32_t ldns_key_inception(const ldns_key *k);
+/**
+ * return the key's expiration date
+ * \param[in] k the key
+ * \return the experiration date
+ */
+uint32_t ldns_key_expiration(const ldns_key *k);
+/**
+ * return the keytag
+ * \param[in] k the key
+ * \return the keytag
+ */
+uint16_t ldns_key_keytag(const ldns_key *k);
+/**
+ * return the public key's owner
+ * \param[in] k the key
+ * \return the owner
+ */
+ldns_rdf *ldns_key_pubkey_owner(const ldns_key *k);
+/**
+ * Set the 'use' flag for all keys in the list
+ * \param[in] keys The key_list
+ * \param[in] v The value to set the use flags to
+ */
+void
+ldns_key_list_set_use(ldns_key_list *keys, bool v);
+
+/**
+ * return the flag of the key
+ * \param[in] k the key
+ * \return the flag
+ */
+uint16_t ldns_key_flags(const ldns_key *k);
+
+/**     
+ * pops the last rr from a keylist
+ * \param[in] key_list the rr_list to pop from
+ * \return NULL if nothing to pop. Otherwise the popped RR
+ */
+ldns_key *ldns_key_list_pop_key(ldns_key_list *key_list);
+
+/** 
+ * converts a ldns_key to a public key rr
+ * If the key data exists at an external point, the corresponding
+ * rdata field must still be added with ldns_rr_rdf_push() to the
+ * result rr of this function
+ *
+ * \param[in] k the ldns_key to convert
+ * \return ldns_rr representation of the key
+ */
+ldns_rr *ldns_key2rr(const ldns_key *k);
+
+/**
+ * print a private key to the file ouput
+ * 
+ * \param[in] output the FILE descriptor where to print to
+ * \param[in] k the ldns_key to print
+ */
+void ldns_key_print(FILE *output, const ldns_key *k);
+
+/**
+ * frees a key structure, but not its internal data structures
+ *
+ * \param[in] key the key object to free
+ */
+void ldns_key_free(ldns_key *key);
+
+/**
+ * frees a key structure and all its internal data structures, except
+ * the data set by ldns_key_set_external_key()
+ *
+ * \param[in] key the key object to free
+ */
+void ldns_key_deep_free(ldns_key *key);
+
+/**
+ * Frees a key list structure
+ * \param[in] key_list the key list object to free
+ */
+void ldns_key_list_free(ldns_key_list *key_list);
+
+/**
+ * Instantiates a DNSKEY or DS RR from file.
+ * \param[in] filename the file to read the record from
+ * \return the corresponding RR, or NULL if the parsing failed
+ */
+ldns_rr * ldns_read_anchor_file(const char *filename);
+
+/**
+ * Returns the 'default base name' for key files;
+ * IE. K\<zone\>+\<alg\>+\<keytag\>
+ * (without the .key or .private)
+ * The memory for this is allocated by this function,
+ * and should be freed by the caller
+ * 
+ * \param[in] key the key to get the file name from
+ * \returns A string containing the file base name
+ */
+char *ldns_key_get_file_base_name(ldns_key *key);
+
+/**
+ * See if a key algorithm is supported
+ * \param[in] algo the signing algorithm number.
+ * \returns true if supported.
+ */
+int ldns_key_algo_supported(int algo);
+
+/**
+ * Get signing algorithm by name.  Comparison is case insensitive.
+ * \param[in] name string with the name.
+ * \returns 0 on parse failure or the algorithm number.
+ */
+ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_KEYS_H */
diff --git a/ldns/include/ldns/ldns.h b/ldns/include/ldns/ldns.h
new file mode 100644
index 0000000..60663ef
--- /dev/null
+++ b/ldns/include/ldns/ldns.h
@@ -0,0 +1,158 @@
+/*
+ * dns.h -- defines for the Domain Name System
+ *
+ * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ * This library was created by:
+ * Jelte Jansen, Erik Rozendaal and Miek Gieben
+ *
+ * A bunch of defines that are used in the DNS.
+ */
+
+
+/**
+\mainpage LDNS Documentation
+
+\section introduction Introduction
+
+The goal of ldns is to simplify DNS programming, it supports recent RFCs
+like the DNSSEC documents, and allow developers to easily create software
+conforming to current RFCs, and experimental software for current Internet
+drafts. A secondary benefit of using ldns is speed, because ldns is written
+in C, and although it is not optimized for performance, it should be a lot
+faster than Perl.
+
+The first main tool to use ldns is Drill, from which part of the library was
+derived. From version 1.0.0 on, drill is included in the ldns release
+and will not be distributed separately anymore. The library also includes some
+other examples and tools to show how it can be used. These can be found in the
+examples/ directory in the tarball.
+
+ldns depends on OpenSSL for it's cryptographic functions.
+Feature list
+
+  - Transparent IPv4 and IPv6 support (overridable if necessary),
+  - TSIG support,
+  - DNSSEC support; signing and verification,
+  - small size,
+  - online documentation as well as manual pages.
+
+If you want to send us patches please use the code from git.
+
+\section using_ldns Using ldns
+
+Almost all interaction between an application and ldns goes through the ldns
+data structures (\ref ldns_rr, \ref ldns_pkt, etc.). These are input or
+output to the functions of ldns. For example, \ref ldns_zone_new_frm_fp
+reads a zone from a \c FILE pointer, and returns an \ref ldns_zone
+structure.
+
+
+Let's use Drill as an example. Drill is a tool much like dig, whose most
+basic function is to send 1 query to a nameserver and print the response.
+
+To be able to do this, drill uses the resolver module of ldns, which acts as
+a stub resolver. The resolver module uses the net module to actually send
+the query that drill requested. It then uses the wire2host module to
+translate the response and place it in ldns' internal structures. These are
+passed back to drill, which then uses the host2str module to print the
+response in presentation format.
+
+\section gettingstarted Getting Started
+
+See the \ref design page for a very high level description of the design
+choices made for ldns. 
+
+For an overview of the functions and types ldns provides, you can check out
+the \ref ldns ldns header file descriptions.
+
+If you want to see some libdns action, you can read our tutorials:
+  - \ref tutorial1_mx
+  - \ref tutorial2_zone
+  - \ref tutorial3_signzone
+
+Or you can just use the menu above to browse through the API docs.
+
+<div style="visibility:hidden;">
+\image html LogoInGradientBar2-y100.png
+</div>
+*/
+
+/**
+ * \file ldns.h
+ *
+ * Including this file will include all ldns files, and define some lookup tables.
+ */
+
+#ifndef LDNS_DNS_H
+#define LDNS_DNS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <ldns/util.h>
+#include <ldns/buffer.h>
+#include <ldns/common.h>
+#include <ldns/dane.h>
+#include <ldns/dname.h>
+#include <ldns/dnssec.h>
+#include <ldns/dnssec_verify.h>
+#include <ldns/dnssec_sign.h>
+#include <ldns/duration.h>
+#include <ldns/error.h>
+#include <ldns/higher.h>
+#include <ldns/host2str.h>
+#include <ldns/host2wire.h>
+#include <ldns/net.h>
+#include <ldns/packet.h>
+#include <ldns/rdata.h>
+#include <ldns/resolver.h>
+#include <ldns/rr.h>
+#include <ldns/str2host.h>
+#include <ldns/tsig.h>
+#include <ldns/update.h>
+#include <ldns/wire2host.h>
+#include <ldns/rr_functions.h>
+#include <ldns/keys.h>
+#include <ldns/parse.h>
+#include <ldns/zone.h>
+#include <ldns/dnssec_zone.h>
+#include <ldns/radix.h>
+#include <ldns/rbtree.h>
+#include <ldns/sha1.h>
+#include <ldns/sha2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LDNS_IP4ADDRLEN      (32/8)
+#define LDNS_IP6ADDRLEN      (128/8)
+#define LDNS_PORT	53
+#define LDNS_ROOT_LABEL_STR     "."
+#define LDNS_DEFAULT_TTL	3600
+
+/* lookup tables for standard DNS stuff  */
+
+/** Taken from RFC 2538, section 2.1.  */
+extern ldns_lookup_table ldns_certificate_types[];
+/** Taken from RFC 2535, section 7.  */
+extern ldns_lookup_table ldns_algorithms[];
+/** Taken from RFC 2538.  */
+extern ldns_lookup_table ldns_cert_algorithms[];
+/** rr types  */
+extern ldns_lookup_table ldns_rr_classes[];
+/** Response codes */
+extern ldns_lookup_table ldns_rcodes[];
+/** Operation codes */
+extern ldns_lookup_table ldns_opcodes[];
+/** EDNS flags */
+extern ldns_lookup_table ldns_edns_flags[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_DNS_H */
diff --git a/ldns/include/ldns/net.h b/ldns/include/ldns/net.h
new file mode 100644
index 0000000..692a9fb
--- /dev/null
+++ b/ldns/include/ldns/net.h
@@ -0,0 +1,207 @@
+/*
+ * net.h
+ *
+ * DNS Resolver definitions
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#ifndef LDNS_NET_H
+#define LDNS_NET_H
+
+#include <ldns/ldns.h>
+#include <sys/socket.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LDNS_DEFAULT_TIMEOUT_SEC 5
+#define LDNS_DEFAULT_TIMEOUT_USEC 0
+
+/**
+ * \file
+ *
+ * Contains functions to send and receive packets over a network.
+ */
+
+/**
+ * Sends a buffer to an ip using udp and return the respons as a ldns_pkt
+ * \param[in] qbin the ldns_buffer to be send
+ * \param[in] to the ip addr to send to
+ * \param[in] tolen length of the ip addr
+ * \param[in] timeout the timeout value for the network
+ * \param[out] answersize size of the packet
+ * \param[out] result packet with the answer
+ * \return status
+ */
+ldns_status ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answersize);
+
+/**
+ * Send an udp query and don't wait for an answer but return
+ * the socket
+ * \param[in] qbin the ldns_buffer to be send
+ * \param[in] to the ip addr to send to
+ * \param[in] tolen length of the ip addr
+ * \param[in] timeout *unused*, was the timeout value for the network
+ * \return the socket used
+ */
+int ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
+
+/**
+ * Send an tcp query and don't wait for an answer but return
+ * the socket
+ * \param[in] qbin the ldns_buffer to be send
+ * \param[in] to the ip addr to send to
+ * \param[in] tolen length of the ip addr
+ * \param[in] timeout the timeout value for the connect attempt
+ * \return the socket used
+ */
+int ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
+
+/**
+ * Sends a buffer to an ip using tcp and return the respons as a ldns_pkt
+ * \param[in] qbin the ldns_buffer to be send
+ * \param[in] qbin the ldns_buffer to be send
+ * \param[in] to the ip addr to send to
+ * \param[in] tolen length of the ip addr
+ * \param[in] timeout the timeout value for the network
+ * \param[out] answersize size of the packet
+ * \param[out] result packet with the answer
+ * \return status
+ */
+ldns_status ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answersize);
+
+/**
+ * Sends ptk to the nameserver at the resolver object. Returns the data
+ * as a ldns_pkt
+ * 
+ * \param[out] pkt packet received from the nameserver
+ * \param[in] r the resolver to use 
+ * \param[in] query_pkt the query to send
+ * \return status
+ */
+ldns_status ldns_send(ldns_pkt **pkt, ldns_resolver *r, const ldns_pkt *query_pkt);
+
+/**
+ * Sends and ldns_buffer (presumably containing a packet to the nameserver at the resolver object. Returns the data
+ * as a ldns_pkt
+ * 
+ * \param[out] pkt packet received from the nameserver
+ * \param[in] r the resolver to use 
+ * \param[in] qb the buffer to send
+ * \param[in] tsig_mac the tsig MAC to authenticate the response with (NULL to do no TSIG authentication)
+ * \return status
+ */
+ldns_status ldns_send_buffer(ldns_pkt **pkt, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac);
+
+/**
+ * Create a tcp socket to the specified address
+ * \param[in] to ip and family
+ * \param[in] tolen length of to
+ * \param[in] timeout timeout for the connect attempt
+ * \return a socket descriptor
+ */
+int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout);
+
+/**
+ * Create a udp socket to the specified address
+ * \param[in] to ip and family
+ * \param[in] timeout *unused*, was timeout for the socket
+ * \return a socket descriptor
+ */
+int ldns_udp_connect(const struct sockaddr_storage *to, struct timeval timeout);
+
+/**
+ * send a query via tcp to a server. Don't want for the answer
+ *
+ * \param[in] qbin the buffer to send
+ * \param[in] sockfd the socket to use
+ * \param[in] to which ip to send it
+ * \param[in] tolen socketlen
+ * \return number of bytes sent
+ */
+ssize_t ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
+
+/**
+ * send a query via udp to a server. Don;t want for the answer
+ *
+ * \param[in] qbin the buffer to send
+ * \param[in] sockfd the socket to use
+ * \param[in] to which ip to send it
+ * \param[in] tolen socketlen
+ * \return number of bytes sent
+ */
+ssize_t ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen);
+
+/**
+ * Gives back a raw packet from the wire and reads the header data from the given
+ * socket. Allocates the data (of size size) itself, so don't forget to free
+ *
+ * \param[in] sockfd the socket to read from
+ * \param[out] size the number of bytes that are read
+ * \param[in] timeout the time allowed between packets.
+ * \return the data read
+ */
+uint8_t *ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout);
+
+/**
+ * This routine may block. Use ldns_tcp_read_wire_timeout, it checks timeouts.
+ * Gives back a raw packet from the wire and reads the header data from the given
+ * socket. Allocates the data (of size size) itself, so don't forget to free
+ *
+ * \param[in] sockfd the socket to read from
+ * \param[out] size the number of bytes that are read
+ * \return the data read
+ */
+uint8_t *ldns_tcp_read_wire(int sockfd, size_t *size);
+
+/**
+ * Gives back a raw packet from the wire and reads the header data from the given
+ * socket. Allocates the data (of size size) itself, so don't forget to free
+ *
+ * \param[in] sockfd the socket to read from
+ * \param[in] fr the address of the client (if applicable)
+ * \param[in] *frlen the lenght of the client's addr (if applicable)
+ * \param[out] size the number of bytes that are read
+ * \return the data read
+ */
+uint8_t *ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *fr, socklen_t *frlen);
+
+/**
+ * returns the native sockaddr representation from the rdf.
+ * \param[in] rd the ldns_rdf to operate on
+ * \param[in] port what port to use. 0 means; use default (53)
+ * \param[out] size what is the size of the sockaddr_storage
+ * \return struct sockaddr* the address in the format so other
+ * functions can use it (sendto)
+ */
+struct sockaddr_storage * ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size);
+
+/**
+ * returns an rdf with the sockaddr info. works for ip4 and ip6
+ * \param[in] sock the struct sockaddr_storage to convert
+ * \param[in] port what port was used. When NULL this is not set
+ * \return ldns_rdf* wth the address
+ */
+ldns_rdf * ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port);
+
+/**
+ * Prepares the resolver for an axfr query
+ * The query is sent and the answers can be read with ldns_axfr_next
+ * \param[in] resolver the resolver to use
+ * \param[in] domain the domain to exfr
+ * \param[in] c the class to use
+ * \return ldns_status the status of the transfer
+ */
+ldns_status ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* LDNS_NET_H */
diff --git a/ldns/include/ldns/packet.h b/ldns/include/ldns/packet.h
new file mode 100644
index 0000000..e66aa34
--- /dev/null
+++ b/ldns/include/ldns/packet.h
@@ -0,0 +1,891 @@
+/*
+ * packet.h
+ *
+ * DNS packet definitions
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file
+ *
+ * Contains the definition of ldns_pkt and its parts, as well
+ * as functions to manipulate those.
+ */
+
+
+#ifndef LDNS_PACKET_H
+#define LDNS_PACKET_H
+
+#define LDNS_MAX_PACKETLEN         65535
+
+/* allow flags to be given to mk_query */
+#define LDNS_QR		1       /* QueRy - query flag */
+#define LDNS_AA		2       /* Authoritative Answer - server flag */
+#define LDNS_TC		4       /* TrunCated - server flag */
+#define LDNS_RD		8       /* Recursion Desired - query flag */
+#define LDNS_CD		16      /* Checking Disabled - query flag */
+#define LDNS_RA		32      /* Recursion Available - server flag */
+#define LDNS_AD		64      /* Authenticated Data - server flag */
+
+#include <ldns/error.h>
+#include <ldns/common.h>
+#include <ldns/rr.h>
+#include <sys/time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* opcodes for pkt's */
+enum ldns_enum_pkt_opcode {
+	LDNS_PACKET_QUERY = 0,
+	LDNS_PACKET_IQUERY = 1,
+	LDNS_PACKET_STATUS = 2, /* there is no 3?? DNS is weird */
+	LDNS_PACKET_NOTIFY = 4,
+	LDNS_PACKET_UPDATE = 5
+};
+typedef enum ldns_enum_pkt_opcode ldns_pkt_opcode;
+
+/* rcodes for pkts */
+enum ldns_enum_pkt_rcode {
+	LDNS_RCODE_NOERROR = 0,
+	LDNS_RCODE_FORMERR = 1,
+	LDNS_RCODE_SERVFAIL = 2,
+	LDNS_RCODE_NXDOMAIN = 3,
+	LDNS_RCODE_NOTIMPL = 4,
+	LDNS_RCODE_REFUSED = 5,
+	LDNS_RCODE_YXDOMAIN = 6,
+	LDNS_RCODE_YXRRSET = 7,
+	LDNS_RCODE_NXRRSET = 8,
+	LDNS_RCODE_NOTAUTH = 9,
+	LDNS_RCODE_NOTZONE = 10
+};
+typedef enum ldns_enum_pkt_rcode ldns_pkt_rcode;
+
+/**
+ *  Header of a dns packet
+ *
+ * Contains the information about the packet itself, as specified in RFC1035
+<pre>
+4.1.1. Header section format
+
+The header contains the following fields:
+
+                                    1  1  1  1  1  1
+      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                      ID                       |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                    QDCOUNT                    |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                    ANCOUNT                    |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                    NSCOUNT                    |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                    ARCOUNT                    |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+where:
+
+ID              A 16 bit identifier assigned by the program that
+                generates any kind of query.  This identifier is copied
+                the corresponding reply and can be used by the requester
+                to match up replies to outstanding queries.
+
+QR              A one bit field that specifies whether this message is a
+                query (0), or a response (1).
+
+OPCODE          A four bit field that specifies kind of query in this
+                message.  This value is set by the originator of a query
+                and copied into the response.  The values are:
+
+                0               a standard query (QUERY)
+
+                1               an inverse query (IQUERY)
+
+                2               a server status request (STATUS)
+
+                3-15            reserved for future use
+
+AA              Authoritative Answer - this bit is valid in responses,
+                and specifies that the responding name server is an
+                authority for the domain name in question section.
+
+                Note that the contents of the answer section may have
+                multiple owner names because of aliases.  The AA bit
+
+                corresponds to the name which matches the query name, or
+                the first owner name in the answer section.
+
+TC              TrunCation - specifies that this message was truncated
+                due to length greater than that permitted on the
+                transmission channel.
+
+RD              Recursion Desired - this bit may be set in a query and
+                is copied into the response.  If RD is set, it directs
+                the name server to pursue the query recursively.
+                Recursive query support is optional.
+
+RA              Recursion Available - this be is set or cleared in a
+                response, and denotes whether recursive query support is
+                available in the name server.
+
+Z               Reserved for future use.  Must be zero in all queries
+                and responses.
+
+RCODE           Response code - this 4 bit field is set as part of
+                responses.  The values have the following
+                interpretation:
+
+                0               No error condition
+
+                1               Format error - The name server was
+                                unable to interpret the query.
+
+                2               Server failure - The name server was
+                                unable to process this query due to a
+                                problem with the name server.
+
+                3               Name Error - Meaningful only for
+                                responses from an authoritative name
+                                server, this code signifies that the
+                                domain name referenced in the query does
+                                not exist.
+
+                4               Not Implemented - The name server does
+                                not support the requested kind of query.
+
+                5               Refused - The name server refuses to
+                                perform the specified operation for
+                                policy reasons.  For example, a name
+                                server may not wish to provide the
+                                information to the particular requester,
+                                or a name server may not wish to perform
+                                a particular operation (e.g., zone
+
+                                transfer) for particular data.
+
+                6-15            Reserved for future use.
+
+QDCOUNT         an unsigned 16 bit integer specifying the number of
+                entries in the question section.
+
+ANCOUNT         an unsigned 16 bit integer specifying the number of
+                resource records in the answer section.
+
+NSCOUNT         an unsigned 16 bit integer specifying the number of name
+                server resource records in the authority records
+                section.
+
+ARCOUNT         an unsigned 16 bit integer specifying the number of
+                resource records in the additional records section.
+
+</pre>
+ */
+struct ldns_struct_hdr
+{
+	/**  Id of a packet */
+	uint16_t _id;
+	/**  Query bit (0=query, 1=answer) */
+	bool _qr;
+	/**  Authoritative answer */
+	bool _aa;
+	/**  Packet truncated */
+	bool _tc;
+	/**  Recursion desired */
+	bool _rd;
+	/**  Checking disabled */
+	bool _cd;
+	/**  Recursion available */
+	bool _ra;
+	/**  Authentic data */
+	bool _ad;
+	/**  Query type */
+	ldns_pkt_opcode _opcode;	 /* XXX 8 bits? */
+	/**  Response code */
+	uint8_t _rcode;
+	/**  question sec */
+	uint16_t _qdcount;
+	/**  answer sec */
+	uint16_t _ancount;
+	/**  auth sec */
+	uint16_t _nscount;
+	/**  add sec */
+	uint16_t _arcount;
+};
+typedef struct ldns_struct_hdr ldns_hdr;
+
+/**
+ * DNS packet
+ *
+ * This structure contains a complete DNS packet (either a query or an answer)
+ *
+ * It is the complete representation of what you actually send to a
+ * nameserver, and what it sends back (assuming you are the client here).
+ */
+struct ldns_struct_pkt
+{
+	/** Header section */
+	ldns_hdr *_header;
+	/* extra items needed in a packet */
+	/** The size of the wire format of the packet in octets */
+	ldns_rdf *_answerfrom;
+        /** Timestamp of the time the packet was sent or created */
+	struct timeval timestamp;
+	/** The duration of the query this packet is an answer to */
+	uint32_t _querytime;
+	/** The size of the wire format of the packet in octets */
+	size_t _size;
+	/** Optional tsig rr */
+	ldns_rr *_tsig_rr;
+	/** EDNS0 available buffer size, see RFC2671 */
+	uint16_t _edns_udp_size;
+	/** EDNS0 Extended rcode */
+	uint8_t _edns_extended_rcode;
+	/** EDNS Version */
+	uint8_t _edns_version;
+        /* OPT pseudo-RR presence flag */
+        uint8_t _edns_present;
+	/** Reserved EDNS data bits */
+	uint16_t _edns_z;
+	/** Arbitrary EDNS rdata */
+	ldns_rdf *_edns_data;
+	/**  Question section */
+	ldns_rr_list	*_question;
+	/**  Answer section */
+	ldns_rr_list	*_answer;
+	/**  Authority section */
+	ldns_rr_list	*_authority;
+	/**  Additional section */
+	ldns_rr_list	*_additional;
+};
+typedef struct ldns_struct_pkt ldns_pkt;
+
+/**
+ * The sections of a packet
+ */
+enum ldns_enum_pkt_section {
+	LDNS_SECTION_QUESTION = 0,
+	LDNS_SECTION_ANSWER = 1,
+	LDNS_SECTION_AUTHORITY = 2,
+	LDNS_SECTION_ADDITIONAL = 3,
+	/** bogus section, if not interested */
+	LDNS_SECTION_ANY = 4,
+	/** used to get all non-question rrs from a packet */
+	LDNS_SECTION_ANY_NOQUESTION = 5
+};
+typedef enum ldns_enum_pkt_section ldns_pkt_section;	
+
+/**
+ * The different types of packets
+ */
+enum ldns_enum_pkt_type {
+	LDNS_PACKET_QUESTION,
+	LDNS_PACKET_REFERRAL,
+	LDNS_PACKET_ANSWER,
+	LDNS_PACKET_NXDOMAIN,
+	LDNS_PACKET_NODATA,
+	LDNS_PACKET_UNKNOWN
+};
+typedef enum ldns_enum_pkt_type ldns_pkt_type;
+
+/* prototypes */
+
+/* read */
+
+/**
+ * Read the packet id
+ * \param[in] p the packet
+ * \return the packet id
+ */
+uint16_t ldns_pkt_id(const ldns_pkt *p);
+/**
+ * Read the packet's qr bit
+ * \param[in] p the packet
+ * \return value of the bit
+ */
+bool ldns_pkt_qr(const ldns_pkt *p);
+/**
+ * Read the packet's aa bit
+ * \param[in] p the packet
+ * \return value of the bit
+ */
+bool ldns_pkt_aa(const ldns_pkt *p);
+/**
+ * Read the packet's tc bit
+ * \param[in] p the packet
+ * \return value of the bit
+ */
+bool ldns_pkt_tc(const ldns_pkt *p);
+/**
+ * Read the packet's rd bit
+ * \param[in] p the packet
+ * \return value of the bit
+ */
+bool ldns_pkt_rd(const ldns_pkt *p);
+/**
+ * Read the packet's cd bit
+ * \param[in] p the packet
+ * \return value of the bit
+ */
+bool ldns_pkt_cd(const ldns_pkt *p);
+/**
+ * Read the packet's ra bit
+ * \param[in] p the packet
+ * \return value of the bit
+ */
+bool ldns_pkt_ra(const ldns_pkt *p);
+/**
+ * Read the packet's ad bit
+ * \param[in] p the packet
+ * \return value of the bit
+ */
+bool ldns_pkt_ad(const ldns_pkt *p);
+/**
+ * Read the packet's code
+ * \param[in] p the packet
+ * \return the opcode
+ */
+ldns_pkt_opcode ldns_pkt_get_opcode(const ldns_pkt *p);
+/**
+ * Return the packet's respons code
+ * \param[in] p the packet
+ * \return the respons code
+ */
+ldns_pkt_rcode ldns_pkt_get_rcode(const ldns_pkt *p);
+/**
+ * Return the packet's qd count 
+ * \param[in] p the packet
+ * \return the qd count
+ */
+uint16_t ldns_pkt_qdcount(const ldns_pkt *p);
+/**
+ * Return the packet's an count
+ * \param[in] p the packet
+ * \return the an count
+ */
+uint16_t ldns_pkt_ancount(const ldns_pkt *p);
+/**
+ * Return the packet's ns count
+ * \param[in] p the packet
+ * \return the ns count
+ */
+uint16_t ldns_pkt_nscount(const ldns_pkt *p);
+/**
+ * Return the packet's ar count
+ * \param[in] p the packet
+ * \return the ar count
+ */
+uint16_t ldns_pkt_arcount(const ldns_pkt *p);
+
+/** 
+ * Return the packet's answerfrom
+ * \param[in] p packet
+ * \return the name of the server
+ */
+ldns_rdf *ldns_pkt_answerfrom(const ldns_pkt *p);
+
+/**
+ * Return the packet's timestamp
+ * \param[in] p the packet
+ * \return the timestamp
+ */
+struct timeval ldns_pkt_timestamp(const ldns_pkt *p);
+/**
+ * Return the packet's querytime
+ * \param[in] p the packet
+ * \return the querytime
+ */
+uint32_t ldns_pkt_querytime(const ldns_pkt *p);
+
+/**
+ * Return the packet's size in bytes
+ * \param[in] p the packet
+ * \return the size
+ */
+size_t ldns_pkt_size(const ldns_pkt *p);
+
+/**
+ * Return the number of RRs in the given section.
+ * Returns the sum of all RRs when LDNS_SECTION_ANY is given.
+ * Returns the sum of all non-question RRs when LDNS_SECTION_ANY_NOQUESTION
+ * is given.
+ * \param[in] p the packet
+ * \param[in] s the section
+ * \return the number of RRs in the given section
+ */
+uint16_t ldns_pkt_section_count(const ldns_pkt *p, ldns_pkt_section s);
+
+/**
+ * Return the packet's tsig pseudo rr's
+ * \param[in] p the packet
+ * \return the tsig rr
+ */
+ldns_rr *ldns_pkt_tsig(const ldns_pkt *p);
+
+/**
+ * Return the packet's question section
+ * \param[in] p the packet
+ * \return the section
+ */
+ldns_rr_list *ldns_pkt_question(const ldns_pkt *p);
+/**
+ * Return the packet's answer section
+ * \param[in] p the packet
+ * \return the section
+ */
+ldns_rr_list *ldns_pkt_answer(const ldns_pkt *p);
+/**
+ * Return the packet's authority section
+ * \param[in] p the packet
+ * \return the section
+ */
+ldns_rr_list *ldns_pkt_authority(const ldns_pkt *p);
+/**
+ * Return the packet's additional section
+ * \param[in] p the packet
+ * \return the section
+ */
+ldns_rr_list *ldns_pkt_additional(const ldns_pkt *p);
+/**
+ * Return the packet's question, answer, authority and additional sections
+ * concatenated, in a new rr_list clone.
+ * \param[in] p the packet
+ * \return the rrs
+ */
+ldns_rr_list *ldns_pkt_all(const ldns_pkt *p);
+/**
+ * Return the packet's answer, authority and additional sections concatenated, 
+ * in a new rr_list clone.  Like ldns_pkt_all but without the questions.
+ * \param[in] p the packet
+ * \return the rrs except the question rrs
+ */
+ldns_rr_list *ldns_pkt_all_noquestion(const ldns_pkt *p);
+
+/**
+ * return all the rr_list's in the packet. Clone the lists, instead
+ * of returning pointers. 
+ * \param[in] p the packet to look in
+ * \param[in] s what section(s) to return
+ * \return ldns_rr_list with the rr's or NULL if none were found
+ */
+ldns_rr_list *ldns_pkt_get_section_clone(const ldns_pkt *p, ldns_pkt_section s);
+
+/**
+ * return all the rr with a specific name from a packet. Optionally
+ * specify from which section in the packet
+ * \param[in] p the packet
+ * \param[in] r the name
+ * \param[in] s the packet's section
+ * \return a list with the rr's or NULL if none were found
+ */
+ldns_rr_list *ldns_pkt_rr_list_by_name(ldns_pkt *p, ldns_rdf *r, ldns_pkt_section s);
+/**
+ * return all the rr with a specific type from a packet. Optionally
+ * specify from which section in the packet
+ * \param[in] p the packet
+ * \param[in] t the type
+ * \param[in] s the packet's section
+ * \return a list with the rr's or NULL if none were found
+ */
+ldns_rr_list *ldns_pkt_rr_list_by_type(const ldns_pkt *p, ldns_rr_type t, ldns_pkt_section s);
+/**
+ * return all the rr with a specific type and type from a packet. Optionally
+ * specify from which section in the packet
+ * \param[in] packet the packet
+ * \param[in] ownername the name
+ * \param[in] type the type
+ * \param[in] sec the packet's section
+ * \return a list with the rr's or NULL if none were found
+ */
+ldns_rr_list *ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet, const ldns_rdf *ownername, ldns_rr_type type, ldns_pkt_section sec);
+
+
+/**
+ * check to see if an rr exist in the packet
+ * \param[in] pkt the packet to examine
+ * \param[in] sec in which section to look
+ * \param[in] rr the rr to look for
+ */
+bool ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr);
+
+
+/**
+ * sets the flags in a packet.
+ * \param[in] pkt the packet to operate on
+ * \param[in] flags ORed values: LDNS_QR| LDNS_AR for instance
+ * \return true on success otherwise false
+ */
+bool ldns_pkt_set_flags(ldns_pkt *pkt, uint16_t flags);
+
+/**
+ * Set the packet's id
+ * \param[in] p the packet
+ * \param[in] id the id to set
+ */
+void ldns_pkt_set_id(ldns_pkt *p, uint16_t id);
+/**
+ * Set the packet's id to a random value
+ * \param[in] p the packet
+ */
+void ldns_pkt_set_random_id(ldns_pkt *p);
+/**
+ * Set the packet's qr bit
+ * \param[in] p the packet
+ * \param[in] b the value to set (boolean)
+ */
+void ldns_pkt_set_qr(ldns_pkt *p, bool b);
+/**
+ * Set the packet's aa bit
+ * \param[in] p the packet
+ * \param[in] b the value to set (boolean)
+ */
+void ldns_pkt_set_aa(ldns_pkt *p, bool b);
+/**
+ * Set the packet's tc bit
+ * \param[in] p the packet
+ * \param[in] b the value to set (boolean)
+ */
+void ldns_pkt_set_tc(ldns_pkt *p, bool b);
+/**
+ * Set the packet's rd bit
+ * \param[in] p the packet
+ * \param[in] b the value to set (boolean)
+ */
+void ldns_pkt_set_rd(ldns_pkt *p, bool b);
+/**
+ * Set the packet's cd bit
+ * \param[in] p the packet
+ * \param[in] b the value to set (boolean)
+ */
+void ldns_pkt_set_cd(ldns_pkt *p, bool b);
+/**
+ * Set the packet's ra bit
+ * \param[in] p the packet
+ * \param[in] b the value to set (boolean)
+ */
+void ldns_pkt_set_ra(ldns_pkt *p, bool b);
+/**
+ * Set the packet's ad bit
+ * \param[in] p the packet
+ * \param[in] b the value to set (boolean)
+ */
+void ldns_pkt_set_ad(ldns_pkt *p, bool b);
+
+/**
+ * Set the packet's opcode
+ * \param[in] p the packet
+ * \param[in] c the opcode
+ */
+void ldns_pkt_set_opcode(ldns_pkt *p, ldns_pkt_opcode c);
+/**
+ * Set the packet's respons code
+ * \param[in] p the packet
+ * \param[in] c the rcode
+ */
+void ldns_pkt_set_rcode(ldns_pkt *p, uint8_t c);
+/**
+ * Set the packet's qd count
+ * \param[in] p the packet
+ * \param[in] c the count
+ */
+void ldns_pkt_set_qdcount(ldns_pkt *p, uint16_t c);
+/**
+ * Set the packet's an count
+ * \param[in] p the packet
+ * \param[in] c the count
+ */
+void ldns_pkt_set_ancount(ldns_pkt *p, uint16_t c);
+/**
+ * Set the packet's ns count
+ * \param[in] p the packet
+ * \param[in] c the count
+ */
+void ldns_pkt_set_nscount(ldns_pkt *p, uint16_t c);
+/**
+ * Set the packet's arcount
+ * \param[in] p the packet
+ * \param[in] c the count
+ */
+void ldns_pkt_set_arcount(ldns_pkt *p, uint16_t c);
+/**
+ * Set the packet's answering server
+ * \param[in] p the packet
+ * \param[in] r the address
+ */
+void ldns_pkt_set_answerfrom(ldns_pkt *p, ldns_rdf *r);
+/**
+ * Set the packet's query time
+ * \param[in] p the packet
+ * \param[in] t the querytime in msec
+ */
+void ldns_pkt_set_querytime(ldns_pkt *p, uint32_t t);
+/**
+ * Set the packet's size
+ * \param[in] p the packet
+ * \param[in] s the size
+ */
+void ldns_pkt_set_size(ldns_pkt *p, size_t s);
+
+/**
+ * Set the packet's timestamp
+ * \param[in] p the packet
+ * \param[in] timeval the timestamp
+ */
+void ldns_pkt_set_timestamp(ldns_pkt *p, struct timeval timeval);
+/**
+ * Set a packet's section count to x
+ * \param[in] p the packet
+ * \param[in] s the section
+ * \param[in] x the section count
+ */
+void ldns_pkt_set_section_count(ldns_pkt *p, ldns_pkt_section s, uint16_t x);
+/**
+ * Set the packet's tsig rr
+ * \param[in] p the packet
+ * \param[in] t the tsig rr
+ */
+void ldns_pkt_set_tsig(ldns_pkt *p, ldns_rr *t);
+
+/**
+ * looks inside the packet to determine
+ * what kind of packet it is, AUTH, NXDOMAIN, REFERRAL, etc.
+ * \param[in] p the packet to examine
+ * \return the type of packet
+ */
+ldns_pkt_type ldns_pkt_reply_type(ldns_pkt *p);
+
+/**
+ * return the packet's edns udp size
+ * \param[in] packet the packet
+ * \return the size
+ */
+uint16_t ldns_pkt_edns_udp_size(const ldns_pkt *packet);
+/**
+ * return the packet's edns extended rcode
+ * \param[in] packet the packet
+ * \return the rcode
+ */
+uint8_t ldns_pkt_edns_extended_rcode(const ldns_pkt *packet);
+/**
+ * return the packet's edns version
+ * \param[in] packet the packet
+ * \return the version
+ */
+uint8_t ldns_pkt_edns_version(const ldns_pkt *packet);
+/**
+ * return the packet's edns z value
+ * \param[in] packet the packet
+ * \return the z value
+ */
+uint16_t ldns_pkt_edns_z(const ldns_pkt *packet);
+/**
+ * return the packet's edns data
+ * \param[in] packet the packet
+ * \return the data
+ */
+ldns_rdf *ldns_pkt_edns_data(const ldns_pkt *packet);
+
+/**
+ * return the packet's edns do bit
+ * \param[in] packet the packet
+ * \return the bit's value
+ */
+bool ldns_pkt_edns_do(const ldns_pkt *packet);
+/**
+ * Set the packet's edns do bit
+ * \param[in] packet the packet
+ * \param[in] value the bit's new value
+ */
+void ldns_pkt_set_edns_do(ldns_pkt *packet, bool value);
+
+/**
+ * returns true if this packet needs and EDNS rr to be sent.
+ * At the moment the only reason is an expected packet
+ * size larger than 512 bytes, but for instance dnssec would
+ * be a good reason too.
+ *
+ * \param[in] packet the packet to check
+ * \return true if packet needs edns rr
+ */
+bool ldns_pkt_edns(const ldns_pkt *packet);
+
+/**
+ * Set the packet's edns udp size
+ * \param[in] packet the packet
+ * \param[in] s the size
+ */
+void ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s);
+/**
+ * Set the packet's edns extended rcode
+ * \param[in] packet the packet
+ * \param[in] c the code
+ */
+void ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c);
+/**
+ * Set the packet's edns version
+ * \param[in] packet the packet
+ * \param[in] v the version
+ */
+void ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v);
+/**
+ * Set the packet's edns z value
+ * \param[in] packet the packet
+ * \param[in] z the value
+ */
+void ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z);
+/**
+ * Set the packet's edns data
+ * \param[in] packet the packet
+ * \param[in] data the data
+ */
+void ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data);
+
+/**
+ * allocates and initializes a ldns_pkt structure.
+ * \return pointer to the new packet
+ */
+ldns_pkt *ldns_pkt_new(void);
+
+/**
+ * frees the packet structure and all data that it contains.
+ * \param[in] packet The packet structure to free
+ * \return void
+ */
+void ldns_pkt_free(ldns_pkt *packet);
+
+/**
+ * creates a query packet for the given name, type, class.
+ * \param[out] p the packet to be returned
+ * \param[in] rr_name the name to query for (as string)
+ * \param[in] rr_type the type to query for
+ * \param[in] rr_class the class to query for
+ * \param[in] flags packet flags
+ * \return LDNS_STATUS_OK or a ldns_status mesg with the error
+ */
+ldns_status ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class , uint16_t flags);
+
+/**
+ * creates an IXFR request packet for the given name, class.
+ * adds the SOA record to the authority section.
+ * \param[out] p the packet to be returned
+ * \param[in] rr_name the name to query for (as string)
+ * \param[in] rr_class the class to query for
+ * \param[in] flags packet flags
+ * \param[in] soa soa record to be added to the authority section
+ * \return LDNS_STATUS_OK or a ldns_status mesg with the error
+ */
+ldns_status ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *rr_name, ldns_rr_class rr_class, uint16_t flags, ldns_rr* soa);
+
+/**
+ * creates a packet with a query in it for the given name, type and class.
+ * \param[in] rr_name the name to query for
+ * \param[in] rr_type the type to query for
+ * \param[in] rr_class the class to query for
+ * \param[in] flags packet flags
+ * \return ldns_pkt* a pointer to the new pkt
+ */
+ldns_pkt *ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags);
+
+/**
+ * creates an IXFR request packet for the given name, type and class.
+ * adds the SOA record to the authority section.
+ * \param[in] rr_name the name to query for
+ * \param[in] rr_class the class to query for
+ * \param[in] flags packet flags
+ * \param[in] soa soa record to be added to the authority section
+ * \return ldns_pkt* a pointer to the new pkt
+ */
+ldns_pkt *ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class, uint16_t flags, ldns_rr* soa);
+
+/**
+ * clones the given packet, creating a fully allocated copy
+ *
+ * \param[in] pkt the packet to clone
+ * \return ldns_pkt* pointer to the new packet
+ */
+ldns_pkt *ldns_pkt_clone(const ldns_pkt *pkt);
+
+/**
+ * directly set the additional section
+ * \param[in] p packet to operate on
+ * \param[in] rr rrlist to set
+ */
+void ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr);
+
+/**
+ * directly set the answer section
+ * \param[in] p packet to operate on
+ * \param[in] rr rrlist to set
+ */
+void ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr);
+
+/**
+ * directly set the question section
+ * \param[in] p packet to operate on
+ * \param[in] rr rrlist to set
+ */
+void ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr);
+
+/**
+ * directly set the auhority section
+ * \param[in] p packet to operate on
+ * \param[in] rr rrlist to set
+ */
+void ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr);
+
+/**
+ * push an rr on a packet
+ * \param[in] packet packet to operate on
+ * \param[in] section where to put it
+ * \param[in] rr rr to push
+ * \return a boolean which is true when the rr was added
+ */
+bool ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr);
+
+/**
+ * push an rr on a packet, provided the RR is not there.
+ * \param[in] pkt packet to operate on
+ * \param[in] sec where to put it
+ * \param[in] rr rr to push
+ * \return a boolean which is true when the rr was added
+ */
+bool ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr);
+
+/**
+ * push a rr_list on a packet
+ * \param[in] packet packet to operate on
+ * \param[in] section where to put it
+ * \param[in] list the rr_list to push
+ * \return a boolean which is true when the rr was added
+ */
+bool ldns_pkt_push_rr_list(ldns_pkt *packet, ldns_pkt_section section, ldns_rr_list *list);
+
+/**
+ * push an rr_list to a packet, provided the RRs are not already there.
+ * \param[in] pkt packet to operate on
+ * \param[in] sec where to put it
+ * \param[in] list the rr_list to push
+ * \return a boolean which is true when the rr was added
+ */
+bool ldns_pkt_safe_push_rr_list(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr_list *list);
+
+/**
+ * check if a packet is empty
+ * \param[in] p packet
+ * \return true: empty, false: not empty
+ */
+bool ldns_pkt_empty(ldns_pkt *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* LDNS_PACKET_H */
diff --git a/ldns/include/ldns/parse.h b/ldns/include/ldns/parse.h
new file mode 100644
index 0000000..0e9034c
--- /dev/null
+++ b/ldns/include/ldns/parse.h
@@ -0,0 +1,167 @@
+/*
+ * parse.h 
+ *
+ * a Net::DNS like library for C
+ * LibDNS Team @ NLnet Labs
+ * (c) NLnet Labs, 2005-2006
+ * See the file LICENSE for the license
+ */
+
+#ifndef LDNS_PARSE_H
+#define LDNS_PARSE_H
+
+#include <ldns/common.h>
+#include <ldns/buffer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LDNS_PARSE_SKIP_SPACE		"\f\n\r\v"
+#define LDNS_PARSE_NORMAL		" \f\n\r\t\v"
+#define LDNS_PARSE_NO_NL		" \t"
+#define LDNS_MAX_LINELEN		10230
+#define LDNS_MAX_KEYWORDLEN		32
+
+
+/**
+ * \file
+ *
+ * Contains some low-level parsing functions, mostly used in the _frm_str
+ * family of functions.
+ */
+ 
+/**
+ * different type of directives in zone files
+ * We now deal with $TTL, $ORIGIN and $INCLUDE.
+ * The latter is not implemented in ldns (yet)
+ */
+enum ldns_enum_directive
+{
+	LDNS_DIR_TTL,
+	LDNS_DIR_ORIGIN,
+	LDNS_DIR_INCLUDE
+};
+typedef enum ldns_enum_directive ldns_directive;
+
+/** 
+ * returns a token/char from the stream F.
+ * This function deals with ( and ) in the stream,
+ * and ignores them when encountered
+ * \param[in] *f the file to read from
+ * \param[out] *token the read token is put here
+ * \param[in] *delim chars at which the parsing should stop
+ * \param[in] *limit how much to read. If 0 the builtin maximum is used
+ * \return 0 on error of EOF of the stream F.  Otherwise return the length of what is read
+ */
+ssize_t ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit);
+
+/** 
+ * returns a token/char from the stream F.
+ * This function deals with ( and ) in the stream,
+ * and ignores when it finds them.
+ * \param[in] *f the file to read from
+ * \param[out] *token the token is put here
+ * \param[in] *delim chars at which the parsing should stop
+ * \param[in] *limit how much to read. If 0 use builtin maximum
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return 0 on error of EOF of F otherwise return the length of what is read
+ */
+ssize_t ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr);
+
+/**
+ * returns a token/char from the buffer b.
+ * This function deals with ( and ) in the buffer,
+ * and ignores when it finds them.
+ * \param[in] *b the buffer to read from
+ * \param[out] *token the token is put here
+ * \param[in] *delim chars at which the parsing should stop
+ * \param[in] *limit how much to read. If 0 the builtin maximum is used
+ * \returns 0 on error of EOF of b. Otherwise return the length of what is read
+ */
+ssize_t ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit);
+
+/*
+ * searches for keyword and delim in a file. Gives everything back
+ * after the keyword + k_del until we hit d_del
+ * \param[in] f file pointer to read from
+ * \param[in] keyword keyword to look for
+ * \param[in] k_del keyword delimeter 
+ * \param[out] data the data found 
+ * \param[in] d_del the data delimeter
+ * \param[in] data_limit maximum size the the data buffer
+ * \return the number of character read
+ */
+ssize_t ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
+
+/*
+ * searches for keyword and delim. Gives everything back
+ * after the keyword + k_del until we hit d_del
+ * \param[in] f file pointer to read from
+ * \param[in] keyword keyword to look for
+ * \param[in] k_del keyword delimeter 
+ * \param[out] data the data found 
+ * \param[in] d_del the data delimeter
+ * \param[in] data_limit maximum size the the data buffer
+ * \param[in] line_nr pointer to an integer containing the current line number (for
+debugging purposes)
+ * \return the number of character read
+ */
+ssize_t ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit, int *line_nr);
+
+/*
+ * searches for keyword and delim in a buffer. Gives everything back
+ * after the keyword + k_del until we hit d_del
+ * \param[in] b buffer pointer to read from
+ * \param[in] keyword keyword to look for
+ * \param[in] k_del keyword delimeter 
+ * \param[out] data the data found 
+ * \param[in] d_del the data delimeter
+ * \param[in] data_limit maximum size the the data buffer
+ * \return the number of character read
+ */
+ssize_t ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
+
+/**
+ * returns the next character from a buffer. Advances the position pointer with 1.
+ * When end of buffer is reached returns EOF. This is the buffer's equivalent
+ * for getc().
+ * \param[in] *buffer buffer to read from
+ * \return EOF on failure otherwise return the character
+ */
+int ldns_bgetc(ldns_buffer *buffer);
+
+/**
+ * skips all of the characters in the given string in the buffer, moving
+ * the position to the first character that is not in *s.
+ * \param[in] *buffer buffer to use
+ * \param[in] *s characters to skip
+ * \return void
+ */
+void ldns_bskipcs(ldns_buffer *buffer, const char *s);
+
+/**
+ * skips all of the characters in the given string in the fp, moving
+ * the position to the first character that is not in *s.
+ * \param[in] *fp file to use
+ * \param[in] *s characters to skip
+ * \return void
+ */
+void ldns_fskipcs(FILE *fp, const char *s);
+
+
+/**
+ * skips all of the characters in the given string in the fp, moving
+ * the position to the first character that is not in *s.
+ * \param[in] *fp file to use
+ * \param[in] *s characters to skip
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return void
+ */
+void ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_PARSE_H */
diff --git a/ldns/include/ldns/radix.h b/ldns/include/ldns/radix.h
new file mode 100644
index 0000000..1885959
--- /dev/null
+++ b/ldns/include/ldns/radix.h
@@ -0,0 +1,240 @@
+/*
+ * radix.h -- generic radix tree
+ *
+ * Copyright (c) 2012, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file
+ * Radix tree. Implementation taken from NSD 4, adjusted for use in ldns.
+ *
+ */
+
+#ifndef LDNS_RADIX_H_
+#define	LDNS_RADIX_H_
+
+#include <ldns/error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint16_t radix_strlen_t;
+typedef struct ldns_radix_array_t ldns_radix_array_t;
+typedef struct ldns_radix_node_t ldns_radix_node_t;
+typedef struct ldns_radix_t ldns_radix_t;
+
+/** Radix node select edge array */
+struct ldns_radix_array_t {
+	/** Additional string after the selection byte for this edge. */
+	uint8_t* str;
+	/** Length of additional string for this edge. */
+	radix_strlen_t len;
+	/** Node that deals with byte+str. */
+	ldns_radix_node_t* edge;
+};
+
+/** A node in a radix tree */
+struct ldns_radix_node_t {
+	/** Key corresponding to this node. */
+	uint8_t* key;
+	/** Key length corresponding to this node. */
+	radix_strlen_t klen;
+	/** Data corresponding to this node. */
+	void* data;
+	/** Parent node. */
+	ldns_radix_node_t* parent;
+	/** Index in the the parent node select edge array. */
+	uint8_t parent_index;
+	/** Length of the array. */
+	uint16_t len;
+	/** Offset of the array. */
+	uint16_t offset;
+	/** Capacity of the array. */
+	uint16_t capacity;
+	/** Select edge array. */
+	ldns_radix_array_t* array;
+};
+
+/** An entire radix tree */
+struct ldns_radix_t {
+	/** Root. */
+	ldns_radix_node_t* root;
+	/** Number of nodes in tree. */
+	size_t count;
+};
+
+/**
+ * Create a new radix tree.
+ * @return: new radix tree.
+ *
+ */
+ldns_radix_t* ldns_radix_create(void);
+
+/**
+ * Initialize radix tree.
+ * @param tree: uninitialized radix tree.
+ *
+ */
+void ldns_radix_init(ldns_radix_t* tree);
+
+/**
+ * Free the radix tree.
+ * @param tree: radix tree.
+ *
+ */
+void ldns_radix_free(ldns_radix_t* tree);
+
+/**
+ * Insert data into the tree.
+ * @param tree: tree to insert to.
+ * @param key:  key.
+ * @param len:  length of key.
+ * @param data: data.
+ * @return: status.
+ *
+ */
+ldns_status ldns_radix_insert(ldns_radix_t* tree, uint8_t* key,
+	radix_strlen_t len, void* data);
+
+/**
+ * Delete data from the tree.
+ * @param tree: tree to insert to.
+ * @param key:  key.
+ * @param len:  length of key.
+ * @return: unlinked data or NULL if not present.
+ *
+ */
+void* ldns_radix_delete(ldns_radix_t* tree, uint8_t* key, radix_strlen_t len);
+
+/**
+ * Search data in the tree.
+ * @param tree: tree to insert to.
+ * @param key:  key.
+ * @param len:  length of key.
+ * @return: the radix node or NULL if not found.
+ *
+ */
+ldns_radix_node_t* ldns_radix_search(ldns_radix_t* tree, uint8_t* key,
+	radix_strlen_t len);
+
+/**
+ * Search data in the tree, and if not found, find the closest smaller
+ * element in the tree.
+ * @param tree: tree to insert to.
+ * @param key:  key.
+ * @param len:  length of key.
+ * @param result: the radix node with the exact or closest match. NULL if
+ *                the key is smaller than the smallest key in the tree.
+ * @return 1 if exact match, 0 otherwise.
+ *
+ */
+int ldns_radix_find_less_equal(ldns_radix_t* tree, uint8_t* key,
+	radix_strlen_t len, ldns_radix_node_t** result);
+
+/**
+ * Get the first element in the tree.
+ * @param tree: tree.
+ * @return: the radix node with the first element.
+ *
+ */
+ldns_radix_node_t* ldns_radix_first(ldns_radix_t* tree);
+
+/**
+ * Get the last element in the tree.
+ * @param tree: tree.
+ * @return: the radix node with the last element.
+ *
+ */
+ldns_radix_node_t* ldns_radix_last(ldns_radix_t* tree);
+
+/**
+ * Next element.
+ * @param node: node.
+ * @return: node with next element.
+ *
+ */
+ldns_radix_node_t* ldns_radix_next(ldns_radix_node_t* node);
+
+/**
+ * Previous element.
+ * @param node: node.
+ * @return: node with previous element.
+ *
+ */
+ldns_radix_node_t* ldns_radix_prev(ldns_radix_node_t* node);
+
+/**
+ * Split radix tree intwo.
+ * @param tree1: one tree.
+ * @param num: number of elements to split off.
+ * @param tree2: another tree.
+ * @return: status.
+ *
+ */
+ldns_status ldns_radix_split(ldns_radix_t* tree1, size_t num,
+	ldns_radix_t** tree2);
+
+/**
+ * Join two radix trees.
+ * @param tree1: one tree.
+ * @param tree2: another tree.
+ * @return: status.
+ *
+ */
+ldns_status ldns_radix_join(ldns_radix_t* tree1, ldns_radix_t* tree2);
+
+/**
+ * Call function for all nodes in the tree, such that leaf nodes are
+ * called before parent nodes.
+ * @param node: start node.
+ * @param func: function.
+ * @param arg: user argument.
+ *
+ */
+void ldns_radix_traverse_postorder(ldns_radix_node_t* node,
+        void (*func)(ldns_radix_node_t*, void*), void* arg);
+
+/**
+ * Print radix tree (for debugging purposes).
+ * @param fd: file descriptor.
+ * @param tree: tree.
+ *
+ */
+void ldns_radix_printf(FILE* fd, ldns_radix_t* tree);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_RADIX_H_ */
diff --git a/ldns/include/ldns/rbtree.h b/ldns/include/ldns/rbtree.h
new file mode 100644
index 0000000..c891934
--- /dev/null
+++ b/ldns/include/ldns/rbtree.h
@@ -0,0 +1,230 @@
+/*
+ * rbtree.h -- generic red-black tree
+ *
+ * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file
+ * Red black tree. Implementation taken from NSD 3.0.5, adjusted for use
+ * in unbound (memory allocation, logging and so on).
+ */
+
+#ifndef LDNS_RBTREE_H_
+#define	LDNS_RBTREE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This structure must be the first member of the data structure in
+ * the rbtree.  This allows easy casting between an rbnode_t and the
+ * user data (poor man's inheritance).
+ * Or you can use the data pointer member to get to your data item.
+ */
+typedef struct ldns_rbnode_t ldns_rbnode_t;
+/**
+ * The rbnode_t struct definition.
+ */
+struct ldns_rbnode_t {
+	/** parent in rbtree, RBTREE_NULL for root */
+	ldns_rbnode_t   *parent;
+	/** left node (smaller items) */
+	ldns_rbnode_t   *left;
+	/** right node (larger items) */
+	ldns_rbnode_t   *right;
+	/** pointer to sorting key */
+	const void *key;
+	/** pointer to data */
+	const void *data;
+	/** colour of this node */
+	uint8_t	    color;
+};
+
+/** The nullpointer, points to empty node */
+#define	LDNS_RBTREE_NULL &ldns_rbtree_null_node
+/** the global empty node */
+extern	ldns_rbnode_t	ldns_rbtree_null_node;
+
+/** An entire red black tree */
+typedef struct ldns_rbtree_t ldns_rbtree_t;
+/** definition for tree struct */
+struct ldns_rbtree_t {
+	/** The root of the red-black tree */
+	ldns_rbnode_t    *root;
+
+	/** The number of the nodes in the tree */
+	size_t       count;
+
+	/**
+	 * Key compare function. <0,0,>0 like strcmp.
+	 * Return 0 on two NULL ptrs.
+	 */
+	int (*cmp) (const void *, const void *);
+};
+
+/**
+ * Create new tree (malloced) with given key compare function.
+ * @param cmpf: compare function (like strcmp) takes pointers to two keys.
+ * @return: new tree, empty.
+ */
+ldns_rbtree_t *ldns_rbtree_create(int (*cmpf)(const void *, const void *));
+
+/**
+ * Free the complete tree (but not its keys)
+ * @param rbtree The tree to free
+ */
+void ldns_rbtree_free(ldns_rbtree_t *rbtree);
+
+/**
+ * Init a new tree (malloced by caller) with given key compare function.
+ * @param rbtree: uninitialised memory for new tree, returned empty.
+ * @param cmpf: compare function (like strcmp) takes pointers to two keys.
+ */
+void ldns_rbtree_init(ldns_rbtree_t *rbtree, int (*cmpf)(const void *, const void *));
+
+/**
+ * Insert data into the tree.
+ * @param rbtree: tree to insert to.
+ * @param data: element to insert.
+ * @return: data ptr or NULL if key already present.
+ */
+ldns_rbnode_t *ldns_rbtree_insert(ldns_rbtree_t *rbtree, ldns_rbnode_t *data);
+
+/**
+ * Insert data into the tree (reversed arguments, for use as callback)
+ * \param[in] data element to insert
+ * \param[out] rbtree tree to insert in to
+ * \return data ptr or NULL if key is already present
+ */
+void ldns_rbtree_insert_vref(ldns_rbnode_t *data, void *rbtree);
+
+/**
+ * Delete element from tree.
+ * @param rbtree: tree to delete from.
+ * @param key: key of item to delete.
+ * @return: node that is now unlinked from the tree. User to delete it.
+ * returns 0 if node not present
+ */
+ldns_rbnode_t *ldns_rbtree_delete(ldns_rbtree_t *rbtree, const void *key);
+
+/**
+ * Find key in tree. Returns NULL if not found.
+ * @param rbtree: tree to find in.
+ * @param key: key that must match.
+ * @return: node that fits or NULL.
+ */
+ldns_rbnode_t *ldns_rbtree_search(ldns_rbtree_t *rbtree, const void *key);
+
+/**
+ * Find, but match does not have to be exact.
+ * @param rbtree: tree to find in.
+ * @param key: key to find position of.
+ * @param result: set to the exact node if present, otherwise to element that
+ *   precedes the position of key in the tree. NULL if no smaller element.
+ * @return: true if exact match in result. Else result points to <= element,
+ * or NULL if key is smaller than the smallest key.
+ */
+int ldns_rbtree_find_less_equal(ldns_rbtree_t *rbtree, const void *key,
+	ldns_rbnode_t **result);
+
+/**
+ * Returns first (smallest) node in the tree
+ * @param rbtree: tree
+ * @return: smallest element or NULL if tree empty.
+ */
+ldns_rbnode_t *ldns_rbtree_first(ldns_rbtree_t *rbtree);
+
+/**
+ * Returns last (largest) node in the tree
+ * @param rbtree: tree
+ * @return: largest element or NULL if tree empty.
+ */
+ldns_rbnode_t *ldns_rbtree_last(ldns_rbtree_t *rbtree);
+
+/**
+ * Returns next larger node in the tree
+ * @param rbtree: tree
+ * @return: next larger element or NULL if no larger in tree.
+ */
+ldns_rbnode_t *ldns_rbtree_next(ldns_rbnode_t *rbtree);
+
+/**
+ * Returns previous smaller node in the tree
+ * @param rbtree: tree
+ * @return: previous smaller element or NULL if no previous in tree.
+ */
+ldns_rbnode_t *ldns_rbtree_previous(ldns_rbnode_t *rbtree);
+
+/**
+ * split off 'elements' number of elements from the start
+ * of the name tree and return a new tree containing those
+ * elements
+ */
+ldns_rbtree_t *ldns_rbtree_split(ldns_rbtree_t *tree, size_t elements);
+
+/**
+ * add all node from the second tree to the first (removing them from the
+ * second), and fix up nsec(3)s if present
+ */
+void ldns_rbtree_join(ldns_rbtree_t *tree1, ldns_rbtree_t *tree2);
+
+/**
+ * Call with node=variable of struct* with rbnode_t as first element.
+ * with type is the type of a pointer to that struct.
+ */
+#define LDNS_RBTREE_FOR(node, type, rbtree) \
+	for(node=(type)ldns_rbtree_first(rbtree); \
+		(ldns_rbnode_t*)node != LDNS_RBTREE_NULL; \
+		node = (type)ldns_rbtree_next((ldns_rbnode_t*)node))
+
+/**
+ * Call function for all elements in the redblack tree, such that
+ * leaf elements are called before parent elements. So that all
+ * elements can be safely free()d.
+ * Note that your function must not remove the nodes from the tree.
+ * Since that may trigger rebalances of the rbtree.
+ * @param tree: the tree
+ * @param func: function called with element and user arg.
+ * 	The function must not alter the rbtree.
+ * @param arg: user argument.
+ */
+void ldns_traverse_postorder(ldns_rbtree_t* tree,
+	void (*func)(ldns_rbnode_t*, void*), void* arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UTIL_RBTREE_H_ */
diff --git a/ldns/include/ldns/rdata.h b/ldns/include/ldns/rdata.h
new file mode 100644
index 0000000..22665b1
--- /dev/null
+++ b/ldns/include/ldns/rdata.h
@@ -0,0 +1,451 @@
+/*
+ * rdata.h
+ *
+ * rdata definitions
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+
+/**
+ * \file
+ *
+ * Defines ldns_rdf and functions to manipulate those.
+ */
+
+
+#ifndef LDNS_RDATA_H
+#define LDNS_RDATA_H
+
+#include <ldns/common.h>
+#include <ldns/error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LDNS_MAX_RDFLEN	65535
+
+#define LDNS_RDF_SIZE_BYTE              1
+#define LDNS_RDF_SIZE_WORD              2
+#define LDNS_RDF_SIZE_DOUBLEWORD        4
+#define LDNS_RDF_SIZE_6BYTES            6
+#define LDNS_RDF_SIZE_8BYTES            8
+#define LDNS_RDF_SIZE_16BYTES           16
+
+#define LDNS_NSEC3_VARS_OPTOUT_MASK 0x01
+
+/**
+ * The different types of RDATA fields.
+ */
+enum ldns_enum_rdf_type
+{
+	/** none */
+	LDNS_RDF_TYPE_NONE,
+	/** domain name */
+	LDNS_RDF_TYPE_DNAME,
+	/** 8 bits */
+	LDNS_RDF_TYPE_INT8,
+	/** 16 bits */
+	LDNS_RDF_TYPE_INT16,
+	/** 32 bits */
+	LDNS_RDF_TYPE_INT32,
+	/** A record */
+	LDNS_RDF_TYPE_A,
+	/** AAAA record */
+	LDNS_RDF_TYPE_AAAA,
+	/** txt string */
+	LDNS_RDF_TYPE_STR,
+	/** apl data */
+	LDNS_RDF_TYPE_APL,
+	/** b32 string */
+	LDNS_RDF_TYPE_B32_EXT,
+	/** b64 string */
+	LDNS_RDF_TYPE_B64,
+	/** hex string */
+	LDNS_RDF_TYPE_HEX,
+	/** nsec type codes */
+	LDNS_RDF_TYPE_NSEC,
+	/** a RR type */
+	LDNS_RDF_TYPE_TYPE,
+	/** a class */
+	LDNS_RDF_TYPE_CLASS,
+	/** certificate algorithm */
+	LDNS_RDF_TYPE_CERT_ALG,
+	/** a key algorithm */
+	LDNS_RDF_TYPE_ALG,
+	/** unknown types */
+	LDNS_RDF_TYPE_UNKNOWN,
+	/** time (32 bits) */
+	LDNS_RDF_TYPE_TIME,
+	/** period */
+	LDNS_RDF_TYPE_PERIOD,
+	/** tsig time 48 bits */
+	LDNS_RDF_TYPE_TSIGTIME,
+	/** Represents the Public Key Algorithm, HIT and Public Key fields
+	    for the HIP RR types.  A HIP specific rdf type is used because of
+	    the unusual layout in wireformat (see RFC 5205 Section 5) */
+	LDNS_RDF_TYPE_HIP,
+	/** variable length any type rdata where the length
+	    is specified by the first 2 bytes */
+	LDNS_RDF_TYPE_INT16_DATA,
+	/** protocol and port bitmaps */
+	LDNS_RDF_TYPE_SERVICE,
+	/** location data */
+	LDNS_RDF_TYPE_LOC,
+	/** well known services */
+	LDNS_RDF_TYPE_WKS,
+	/** NSAP */
+	LDNS_RDF_TYPE_NSAP,
+	/** ATMA */
+	LDNS_RDF_TYPE_ATMA,
+	/** IPSECKEY */
+	LDNS_RDF_TYPE_IPSECKEY,
+	/** nsec3 hash salt */
+	LDNS_RDF_TYPE_NSEC3_SALT,
+	/** nsec3 base32 string (with length byte on wire */
+	LDNS_RDF_TYPE_NSEC3_NEXT_OWNER,
+
+	/** 4 shorts represented as 4 * 16 bit hex numbers
+	 *  separated by colons. For NID and L64.
+	 */
+	LDNS_RDF_TYPE_ILNP64,
+
+	/** 6 * 8 bit hex numbers separated by dashes. For EUI48. */
+	LDNS_RDF_TYPE_EUI48,
+	/** 8 * 8 bit hex numbers separated by dashes. For EUI64. */
+	LDNS_RDF_TYPE_EUI64,
+
+	/** A non-zero sequence of US-ASCII letters and numbers in lower case.
+	 *  For CAA.
+	 */
+	LDNS_RDF_TYPE_TAG,
+
+	/** A <character-string> encoding of the value field as specified 
+	 * [RFC1035], Section 5.1., encoded as remaining rdata.
+	 * For CAA.
+	 */
+	LDNS_RDF_TYPE_LONG_STR,
+
+	/** Since RFC7218 TLSA records can be given with mnemonics,
+	 * hence these rdata field types.  But as with DNSKEYs, the output
+	 * is always numeric.
+	 */
+	LDNS_RDF_TYPE_CERTIFICATE_USAGE,
+	LDNS_RDF_TYPE_SELECTOR,
+	LDNS_RDF_TYPE_MATCHING_TYPE,
+
+	/* Aliases */
+	LDNS_RDF_TYPE_BITMAP = LDNS_RDF_TYPE_NSEC
+};
+typedef enum ldns_enum_rdf_type ldns_rdf_type;
+
+/**
+ * algorithms used in CERT rrs
+ */
+enum ldns_enum_cert_algorithm
+{
+        LDNS_CERT_PKIX		= 1,
+        LDNS_CERT_SPKI		= 2,
+        LDNS_CERT_PGP		= 3,
+        LDNS_CERT_IPKIX         = 4,
+        LDNS_CERT_ISPKI         = 5,
+        LDNS_CERT_IPGP          = 6,
+        LDNS_CERT_ACPKIX        = 7,
+        LDNS_CERT_IACPKIX       = 8,
+        LDNS_CERT_URI		= 253,
+        LDNS_CERT_OID		= 254
+};
+typedef enum ldns_enum_cert_algorithm ldns_cert_algorithm;
+
+
+
+/**
+ * Resource record data field.
+ *
+ * The data is a network ordered array of bytes, which size is specified by
+ * the (16-bit) size field. To correctly parse it, use the type
+ * specified in the (16-bit) type field with a value from \ref ldns_rdf_type.
+ */
+struct ldns_struct_rdf
+{
+	/** The size of the data (in octets) */
+	size_t _size;
+	/** The type of the data */
+	ldns_rdf_type _type;
+	/** Pointer to the data (raw octets) */
+	void  *_data;
+};
+typedef struct ldns_struct_rdf ldns_rdf;
+
+/* prototypes */
+
+/* write access functions */
+
+/**
+ * sets the size of the rdf.
+ * \param[in] *rd the rdf to operate on
+ * \param[in] size the new size
+ * \return void
+ */
+void ldns_rdf_set_size(ldns_rdf *rd, size_t size);
+
+/**
+ * sets the size of the rdf.
+ * \param[in] *rd the rdf to operate on
+ * \param[in] type the new type
+ * \return void
+ */
+void ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type);
+
+/**
+ * sets the size of the rdf.
+ * \param[in] *rd the rdf to operate on
+ * \param[in] *data pointer to the new data
+ * \return void
+ */
+void ldns_rdf_set_data(ldns_rdf *rd, void *data);
+
+/* read access */
+
+/**
+ * returns the size of the rdf.
+ * \param[in] *rd the rdf to read from
+ * \return uint16_t with the size
+ */
+size_t ldns_rdf_size(const ldns_rdf *rd);
+
+/**
+ * returns the type of the rdf. We need to insert _get_
+ * here to prevent conflict the the rdf_type TYPE.
+ * \param[in] *rd the rdf to read from
+ * \return ldns_rdf_type with the type
+ */
+ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd);
+
+/**
+ * returns the data of the rdf.
+ * \param[in] *rd the rdf to read from
+ *
+ * \return uint8_t* pointer to the rdf's data
+ */
+uint8_t *ldns_rdf_data(const ldns_rdf *rd);
+
+/* creator functions */
+
+/**
+ * allocates a new rdf structure and fills it.
+ * This function DOES NOT copy the contents from
+ * the buffer, unlinke ldns_rdf_new_frm_data()
+ * \param[in] type type of the rdf
+ * \param[in] size size of the buffer
+ * \param[in] data pointer to the buffer to be copied
+ * \return the new rdf structure or NULL on failure
+ */
+ldns_rdf *ldns_rdf_new(ldns_rdf_type type, size_t size, void *data);
+
+/**
+ * allocates a new rdf structure and fills it.
+ * This function _does_ copy the contents from
+ * the buffer, unlinke ldns_rdf_new()
+ * \param[in] type type of the rdf
+ * \param[in] size size of the buffer
+ * \param[in] data pointer to the buffer to be copied
+ * \return the new rdf structure or NULL on failure
+ */
+ldns_rdf *ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data);
+
+/**
+ * creates a new rdf from a string.
+ * \param[in] type   type to use
+ * \param[in] str string to use
+ * \return ldns_rdf* or NULL in case of an error
+ */
+ldns_rdf *ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str);
+
+/**
+ * creates a new rdf from a file containing a string.
+ * \param[out] r the new rdf
+ * \param[in] type   type to use
+ * \param[in] fp the file pointer  to use
+ * \return LDNS_STATUS_OK or the error
+ */
+ldns_status ldns_rdf_new_frm_fp(ldns_rdf **r, ldns_rdf_type type, FILE *fp);
+
+/**
+ * creates a new rdf from a file containing a string.
+ * \param[out] r the new rdf
+ * \param[in] type   type to use
+ * \param[in] fp the file pointer  to use
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return LDNS_STATUS_OK or the error
+ */
+ldns_status ldns_rdf_new_frm_fp_l(ldns_rdf **r, ldns_rdf_type type, FILE *fp, int *line_nr);
+
+/* destroy functions */
+
+/**
+ * frees a rdf structure, leaving the
+ * data pointer intact.
+ * \param[in] rd the pointer to be freed
+ * \return void
+ */
+void ldns_rdf_free(ldns_rdf *rd);
+
+/**
+ * frees a rdf structure _and_ frees the
+ * data. rdf should be created with _new_frm_data
+ * \param[in] rd the rdf structure to be freed
+ * \return void
+ */
+void ldns_rdf_deep_free(ldns_rdf *rd);
+
+/* conversion functions */
+
+/**
+ * returns the rdf containing the native uint8_t repr.
+ * \param[in] type the ldns_rdf type to use
+ * \param[in] value the uint8_t to use
+ * \return ldns_rdf* with the converted value
+ */
+ldns_rdf *ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value);
+
+/**
+ * returns the rdf containing the native uint16_t representation.
+ * \param[in] type the ldns_rdf type to use
+ * \param[in] value the uint16_t to use
+ * \return ldns_rdf* with the converted value
+ */
+ldns_rdf *ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value);
+
+/**
+ * returns an rdf that contains the given int32 value.
+ *
+ * Because multiple rdf types can contain an int32, the
+ * type must be specified
+ * \param[in] type the ldns_rdf type to use
+ * \param[in] value the uint32_t to use
+ * \return ldns_rdf* with the converted value
+ */
+ldns_rdf *ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value);
+
+/**
+ * returns an int16_data rdf that contains the data in the
+ * given array, preceded by an int16 specifying the length.
+ *
+ * The memory is copied, and an LDNS_RDF_TYPE_INT16DATA is returned
+ * \param[in] size the size of the data
+ * \param[in] *data pointer to the actual data
+ *
+ * \return ldns_rd* the rdf with the data
+ */
+ldns_rdf *ldns_native2rdf_int16_data(size_t size, uint8_t *data);
+
+/**
+ * reverses an rdf, only actually useful for AAAA and A records.
+ * The returned rdf has the type LDNS_RDF_TYPE_DNAME!
+ * \param[in] *rd rdf to be reversed
+ * \return the reversed rdf (a newly created rdf)
+ */
+ldns_rdf *ldns_rdf_address_reverse(ldns_rdf *rd);
+
+/**
+ * returns the native uint8_t representation from the rdf.
+ * \param[in] rd the ldns_rdf to operate on
+ * \return uint8_t the value extracted
+ */
+uint8_t 	ldns_rdf2native_int8(const ldns_rdf *rd);
+
+/**
+ * returns the native uint16_t representation from the rdf.
+ * \param[in] rd the ldns_rdf to operate on
+ * \return uint16_t the value extracted
+ */
+uint16_t	ldns_rdf2native_int16(const ldns_rdf *rd);
+
+/**
+ * returns the native uint32_t representation from the rdf.
+ * \param[in] rd the ldns_rdf to operate on
+ * \return uint32_t the value extracted
+ */
+uint32_t ldns_rdf2native_int32(const ldns_rdf *rd);
+
+/**
+ * returns the native time_t representation from the rdf.
+ * \param[in] rd the ldns_rdf to operate on
+ * \return time_t the value extracted (32 bits currently)
+ */
+time_t ldns_rdf2native_time_t(const ldns_rdf *rd);
+
+/**
+ * converts a ttl value (like 5d2h) to a long.
+ * \param[in] nptr the start of the string
+ * \param[out] endptr points to the last char in case of error
+ * \return the convert duration value
+ */
+uint32_t ldns_str2period(const char *nptr, const char **endptr);
+
+/**
+ * removes \\DDD, \\[space] and other escapes from the input.
+ * See RFC 1035, section 5.1.
+ * \param[in] word what to check
+ * \param[in] length the string
+ * \return ldns_status mesg
+ */
+ldns_status ldns_octet(char *word, size_t *length);
+
+/**
+ * clones a rdf structure. The data is copied.
+ * \param[in] rd rdf to be copied
+ * \return a new rdf structure
+ */
+ldns_rdf *ldns_rdf_clone(const ldns_rdf *rd);
+
+/**
+ * compares two rdf's on their wire formats.
+ * (To order dnames according to rfc4034, use ldns_dname_compare)
+ * \param[in] rd1 the first one
+ * \param[in] rd2 the second one
+ * \return 0 if equal
+ * \return -1 if rd1 comes before rd2
+ * \return +1 if rd2 comes before rd1
+ */
+int ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2);
+
+/**
+ * Gets the algorithm value, the HIT and Public Key data from the rdf with
+ * type LDNS_RDF_TYPE_HIP.
+ * \param[in] rdf the rdf with type LDNS_RDF_TYPE_HIP
+ * \param[out] alg      the algorithm
+ * \param[out] hit_size the size of the HIT data
+ * \param[out] hit      the hit data
+ * \param[out] pk_size  the size of the Public Key data
+ * \param[out] pk       the  Public Key data
+ * \return LDNS_STATUS_OK on success, and the error otherwise
+ */
+ldns_status ldns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg,
+		uint8_t *hit_size, uint8_t** hit,
+		uint16_t *pk_size, uint8_t** pk);
+
+/**
+ * Creates a new LDNS_RDF_TYPE_HIP rdf from given data.
+ * \param[out] rdf      the newly created LDNS_RDF_TYPE_HIP rdf
+ * \param[in]  alg      the algorithm
+ * \param[in]  hit_size the size of the HIT data
+ * \param[in]  hit      the hit data
+ * \param[in]  pk_size  the size of the Public Key data
+ * \param[in]  pk       the  Public Key data
+ * \return LDNS_STATUS_OK on success, and the error otherwise
+ */
+ldns_status ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf** rdf, uint8_t alg,
+		uint8_t hit_size, uint8_t *hit, uint16_t pk_size, uint8_t *pk);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* LDNS_RDATA_H */
diff --git a/ldns/include/ldns/resolver.h b/ldns/include/ldns/resolver.h
new file mode 100644
index 0000000..228485c
--- /dev/null
+++ b/ldns/include/ldns/resolver.h
@@ -0,0 +1,805 @@
+/*
+ * resolver.h
+ *
+ * DNS Resolver definitions
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file
+ *
+ * Defines the  ldns_resolver structure, a stub resolver that can send queries and parse answers.
+ *
+ */
+
+#ifndef LDNS_RESOLVER_H
+#define LDNS_RESOLVER_H
+
+#include <ldns/error.h>
+#include <ldns/common.h>
+#include <ldns/rr.h>
+#include <ldns/tsig.h>
+#include <ldns/rdata.h>
+#include <ldns/packet.h>
+#include <sys/time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Default location of the resolv.conf file */
+#define LDNS_RESOLV_CONF	"/etc/resolv.conf"
+/** Default location of the hosts file */
+#define LDNS_RESOLV_HOSTS	"/etc/hosts"
+
+#define LDNS_RESOLV_KEYWORD     -1
+#define LDNS_RESOLV_DEFDOMAIN	0
+#define LDNS_RESOLV_NAMESERVER	1
+#define LDNS_RESOLV_SEARCH	2
+#define LDNS_RESOLV_SORTLIST	3
+#define LDNS_RESOLV_OPTIONS	4
+#define LDNS_RESOLV_ANCHOR	5
+#define LDNS_RESOLV_KEYWORDS    6
+
+#define LDNS_RESOLV_INETANY		0
+#define LDNS_RESOLV_INET		1
+#define LDNS_RESOLV_INET6		2
+
+#define LDNS_RESOLV_RTT_INF             0       /* infinity */
+#define LDNS_RESOLV_RTT_MIN             1       /* reachable */
+
+/**
+ * DNS stub resolver structure
+ */
+struct ldns_struct_resolver
+{
+	/**  Port to send queries to */
+	uint16_t _port;
+
+	/** Array of nameservers to query (IP addresses or dnames) */
+	ldns_rdf **_nameservers;
+	/** Number of nameservers in \c _nameservers */
+	size_t _nameserver_count; /* how many do we have */
+
+	/**  Round trip time; 0 -> infinity. Unit: ms? */
+	size_t *_rtt;
+
+	/**  Whether or not to be recursive */
+	bool _recursive;
+
+	/**  Print debug information */
+	bool _debug;
+
+	/**  Default domain to add to non fully qualified domain names */
+	ldns_rdf *_domain;
+
+	/**  Searchlist array, add the names in this array if a query cannot be found */
+	ldns_rdf **_searchlist;
+
+	/** Number of entries in the searchlist array */
+	size_t _searchlist_count;
+
+	/**  Number of times to retry before giving up */
+	uint8_t _retry;
+	/**  Time to wait before retrying */
+	uint8_t _retrans;
+	/**  Use new fallback mechanism (try EDNS, then do TCP) */
+	bool _fallback;
+
+	/**  Whether to do DNSSEC */
+	bool _dnssec;
+	/**  Whether to set the CD bit on DNSSEC requests */
+	bool _dnssec_cd;
+	/** Optional trust anchors for complete DNSSEC validation */
+	ldns_rr_list * _dnssec_anchors;
+	/**  Whether to use tcp or udp (tcp if the value is true)*/
+	bool _usevc;
+	/**  Whether to ignore the tc bit */
+	bool _igntc;
+	/**  Whether to use ip6: 0->does not matter, 1 is IPv4, 2 is IPv6 */
+	uint8_t _ip6;
+	/**  If true append the default domain */
+	bool _defnames;
+	/**  If true apply the search list */
+	bool _dnsrch;
+	/**  Timeout for socket connections */
+	struct timeval _timeout;
+	/**  Only try the first nameserver, and return with an error directly if it fails */
+	bool _fail;
+	/**  Randomly choose a nameserver */
+	bool _random;
+	/** Keep some things to make AXFR possible */
+	int _socket;
+	/** Count the number of LDNS_RR_TYPE_SOA RRs we have seen so far
+	 * (the second one signifies the end of the AXFR)
+	 */
+	int _axfr_soa_count;
+	/* when axfring we get complete packets from the server
+	   but we want to give the caller 1 rr at a time, so
+	   keep the current pkt */
+        /** Packet currently handled when doing part of an AXFR */
+	ldns_pkt *_cur_axfr_pkt;
+	/** Counter for within the AXFR packets */
+	uint16_t _axfr_i;
+	/* EDNS0 available buffer size */
+	uint16_t _edns_udp_size;
+	/* serial for IXFR */
+	uint32_t _serial;
+
+	/* Optional tsig key for signing queries,
+	outgoing messages are signed if and only if both are set
+	*/
+	/** Name of the key to use with TSIG, if _tsig_keyname and _tsig_keydata both contain values, outgoing messages are automatically signed with TSIG. */
+	char *_tsig_keyname;
+	/** Secret key data to use with TSIG, if _tsig_keyname and _tsig_keydata both contain values, outgoing messages are automatically signed with TSIG. */
+	char *_tsig_keydata;
+	/** TSIG signing algorithm */
+	char *_tsig_algorithm;
+
+	/** Source address to query from */
+	ldns_rdf *_source;
+};
+typedef struct ldns_struct_resolver ldns_resolver;
+
+/* prototypes */
+/* read access functions */
+
+/**
+ * Get the port the resolver should use
+ * \param[in] r the resolver
+ * \return the port number
+ */
+uint16_t ldns_resolver_port(const ldns_resolver *r);
+
+/**
+ * Get the source address the resolver should use
+ * \param[in] r the resolver
+ * \return the source rdf
+ */
+ldns_rdf *ldns_resolver_source(const ldns_resolver *r);
+
+/**
+ * Is the resolver set to recurse
+ * \param[in] r the resolver
+ * \return true if so, otherwise false
+ */
+bool ldns_resolver_recursive(const ldns_resolver *r);
+
+/**
+ * Get the debug status of the resolver
+ * \param[in] r the resolver
+ * \return true if so, otherwise false
+ */
+bool ldns_resolver_debug(const ldns_resolver *r);
+
+/**
+ * Get the number of retries
+ * \param[in] r the resolver
+ * \return the number of retries
+ */
+uint8_t ldns_resolver_retry(const ldns_resolver *r);
+
+/**
+ * Get the retransmit interval
+ * \param[in] r the resolver
+ * \return the retransmit interval
+ */
+uint8_t ldns_resolver_retrans(const ldns_resolver *r);
+
+/**
+ * Get the truncation fallback status
+ * \param[in] r the resolver
+ * \return whether the truncation fallback mechanism is used
+ */
+bool ldns_resolver_fallback(const ldns_resolver *r);
+
+/**
+ * Does the resolver use ip6 or ip4
+ * \param[in] r the resolver
+ * \return 0: both, 1: ip4, 2:ip6
+ */
+uint8_t ldns_resolver_ip6(const ldns_resolver *r);
+
+/**
+ * Get the resolver's udp size
+ * \param[in] r the resolver
+ * \return the udp mesg size
+ */
+uint16_t ldns_resolver_edns_udp_size(const ldns_resolver *r);
+/**
+ * Does the resolver use tcp or udp
+ * \param[in] r the resolver
+ * \return true: tcp, false: udp
+ */
+bool ldns_resolver_usevc(const ldns_resolver *r);
+/**
+ * Does the resolver only try the first nameserver
+ * \param[in] r the resolver
+ * \return true: yes, fail, false: no, try the others
+ */
+bool ldns_resolver_fail(const ldns_resolver *r);
+/**
+ * Does the resolver apply default domain name
+ * \param[in] r the resolver
+ * \return true: yes, false: no
+ */
+bool ldns_resolver_defnames(const ldns_resolver *r);
+/**
+ * Does the resolver apply search list
+ * \param[in] r the resolver
+ * \return true: yes, false: no
+ */
+bool ldns_resolver_dnsrch(const ldns_resolver *r);
+/**
+ * Does the resolver do DNSSEC
+ * \param[in] r the resolver
+ * \return true: yes, false: no
+ */
+bool ldns_resolver_dnssec(const ldns_resolver *r);
+/**
+ * Does the resolver set the CD bit
+ * \param[in] r the resolver
+ * \return true: yes, false: no
+ */
+bool ldns_resolver_dnssec_cd(const ldns_resolver *r);
+/**
+ * Get the resolver's DNSSEC anchors
+ * \param[in] r the resolver
+ * \return an rr_list containg trusted DNSSEC anchors
+ */
+ldns_rr_list * ldns_resolver_dnssec_anchors(const ldns_resolver *r);
+/**
+ * Does the resolver ignore the TC bit (truncated)
+ * \param[in] r the resolver
+ * \return true: yes, false: no
+ */
+bool ldns_resolver_igntc(const ldns_resolver *r);
+/**
+ * Does the resolver randomize the nameserver before usage
+ * \param[in] r the resolver
+ * \return true: yes, false: no
+ */
+bool ldns_resolver_random(const ldns_resolver *r);
+/**
+ * How many nameserver are configured in the resolver
+ * \param[in] r the resolver
+ * \return number of nameservers
+ */
+size_t ldns_resolver_nameserver_count(const ldns_resolver *r);
+/**
+ * What is the default dname to add to relative queries
+ * \param[in] r the resolver
+ * \return the dname which is added
+ */
+ldns_rdf *ldns_resolver_domain(const ldns_resolver *r);
+/**
+ * What is the timeout on socket connections
+ * \param[in] r the resolver
+ * \return the timeout as struct timeval
+ */
+struct timeval ldns_resolver_timeout(const ldns_resolver *r);
+/**
+ * What is the searchlist as used by the resolver
+ * \param[in] r the resolver
+ * \return a ldns_rdf pointer to a list of the addresses
+ */
+ldns_rdf** ldns_resolver_searchlist(const ldns_resolver *r);
+/**
+ * Return the configured nameserver ip address
+ * \param[in] r the resolver
+ * \return a ldns_rdf pointer to a list of the addresses
+ */
+ldns_rdf** ldns_resolver_nameservers(const ldns_resolver *r);
+/**
+ * Return the used round trip times for the nameservers
+ * \param[in] r the resolver
+ * \return a size_t* pointer to the list.
+ * yet)
+ */
+size_t * ldns_resolver_rtt(const ldns_resolver *r);
+/**
+ * Return the used round trip time for a specific nameserver
+ * \param[in] r the resolver
+ * \param[in] pos the index to the nameserver
+ * \return the rrt, 0: infinite, >0: undefined (as of * yet)
+ */
+size_t ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos);
+/**
+ * Return the tsig keyname as used by the nameserver
+ * \param[in] r the resolver
+ * \return the name used.
+ */
+char *ldns_resolver_tsig_keyname(const ldns_resolver *r);
+/**
+ * Return the tsig algorithm as used by the nameserver
+ * \param[in] r the resolver
+ * \return the algorithm used.
+ */
+char *ldns_resolver_tsig_algorithm(const ldns_resolver *r);
+/**
+ * Return the tsig keydata as used by the nameserver
+ * \param[in] r the resolver
+ * \return the keydata used.
+ */
+char *ldns_resolver_tsig_keydata(const ldns_resolver *r);
+/**
+ * pop the last nameserver from the resolver.
+ * \param[in] r the resolver
+ * \return the popped address or NULL if empty
+ */
+ldns_rdf* ldns_resolver_pop_nameserver(ldns_resolver *r);
+
+/**
+ * Return the resolver's searchlist count
+ * \param[in] r the resolver
+ * \return the searchlist count
+ */
+size_t ldns_resolver_searchlist_count(const ldns_resolver *r);
+
+/* write access function */
+/**
+ * Set the port the resolver should use
+ * \param[in] r the resolver
+ * \param[in] p the port number
+ */
+void ldns_resolver_set_port(ldns_resolver *r, uint16_t p);
+
+/**
+ * Set the source rdf (address) the resolver should use
+ * \param[in] r the resolver
+ * \param[in] s the source address
+ */
+void ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s);
+
+/**
+ * Set the resolver recursion
+ * \param[in] r the resolver
+ * \param[in] b true: set to recurse, false: unset
+ */
+void ldns_resolver_set_recursive(ldns_resolver *r, bool b);
+
+/**
+ * Set the resolver debugging
+ * \param[in] r the resolver
+ * \param[in] b true: debug on: false debug off
+ */
+void ldns_resolver_set_debug(ldns_resolver *r, bool b);
+
+/**
+ * Incremental the resolver's nameserver count.
+ * \param[in] r the resolver
+ */
+void ldns_resolver_incr_nameserver_count(ldns_resolver *r);
+
+/**
+ * Decrement the resolver's nameserver count.
+ * \param[in] r the resolver
+ */
+void ldns_resolver_dec_nameserver_count(ldns_resolver *r);
+
+/**
+ * Set the resolver's nameserver count directly.
+ * \param[in] r the resolver
+ * \param[in] c the nameserver count
+ */
+void ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c);
+
+/**
+ * Set the resolver's nameserver count directly by using an rdf list
+ * \param[in] r the resolver
+ * \param[in] rd the resolver addresses
+ */
+void ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **rd);
+
+/**
+ * Set the resolver's default domain. This gets appended when no
+ * absolute name is given
+ * \param[in] r the resolver
+ * \param[in] rd the name to append
+ */
+void ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *rd);
+
+/**
+ * Set the resolver's socket time out when talking to remote hosts
+ * \param[in] r the resolver
+ * \param[in] timeout the timeout to use
+ */
+void ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout);
+
+/**
+ * Push a new rd to the resolver's searchlist
+ * \param[in] r the resolver
+ * \param[in] rd to push
+ */
+void ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *rd);
+
+/**
+ * Whether the resolver uses the name set with _set_domain
+ * \param[in] r the resolver
+ * \param[in] b true: use the defaults, false: don't use them
+ */
+void ldns_resolver_set_defnames(ldns_resolver *r, bool b);
+
+/**
+ * Whether the resolver uses a virtual circuit (TCP)
+ * \param[in] r the resolver
+ * \param[in] b true: use TCP, false: don't use TCP
+ */
+void ldns_resolver_set_usevc(ldns_resolver *r, bool b);
+
+/**
+ * Whether the resolver uses the searchlist
+ * \param[in] r the resolver
+ * \param[in] b true: use the list, false: don't use the list
+ */
+void ldns_resolver_set_dnsrch(ldns_resolver *r, bool b);
+
+/**
+ * Whether the resolver uses DNSSEC
+ * \param[in] r the resolver
+ * \param[in] b true: use DNSSEC, false: don't use DNSSEC
+ */
+void ldns_resolver_set_dnssec(ldns_resolver *r, bool b);
+
+/**
+ * Whether the resolver uses the checking disable bit
+ * \param[in] r the resolver
+ * \param[in] b true: enable , false: don't use TCP
+ */
+void ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool b);
+/**
+ * Set the resolver's DNSSEC anchor list directly. RRs should be of type DS or DNSKEY.
+ * \param[in] r the resolver
+ * \param[in] l the list of RRs to use as trust anchors
+ */
+void ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l);
+
+/**
+ * Push a new trust anchor to the resolver. It must be a DS or DNSKEY rr
+ * \param[in] r the resolver.
+ * \param[in] rr the RR to add as a trust anchor.
+ * \return a status
+ */
+ldns_status ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr);
+
+/**
+ * Set the resolver retrans timeout (in seconds)
+ * \param[in] r the resolver
+ * \param[in] re the retransmission interval in seconds
+ */
+void ldns_resolver_set_retrans(ldns_resolver *r, uint8_t re);
+
+/**
+ * Set whether the resolvers truncation fallback mechanism is used
+ * when ldns_resolver_query() is called.
+ * \param[in] r the resolver
+ * \param[in] fallback whether to use the fallback mechanism
+ */
+void ldns_resolver_set_fallback(ldns_resolver *r, bool fallback);
+
+/**
+ * Set the number of times a resolver should retry a nameserver before the
+ * next one is tried.
+ * \param[in] r the resolver
+ * \param[in] re the number of retries
+ */
+void ldns_resolver_set_retry(ldns_resolver *r, uint8_t re);
+
+/**
+ * Whether the resolver uses ip6
+ * \param[in] r the resolver
+ * \param[in] i 0: no pref, 1: ip4, 2: ip6
+ */
+void ldns_resolver_set_ip6(ldns_resolver *r, uint8_t i);
+
+/**
+ * Whether or not to fail after one failed query
+ * \param[in] r the resolver
+ * \param[in] b true: yes fail, false: continue with next nameserver
+ */
+void ldns_resolver_set_fail(ldns_resolver *r, bool b);
+
+/**
+ * Whether or not to ignore the TC bit
+ * \param[in] r the resolver
+ * \param[in] b true: yes ignore, false: don't ignore
+ */
+void ldns_resolver_set_igntc(ldns_resolver *r, bool b);
+
+/**
+ * Set maximum udp size
+ * \param[in] r the resolver
+ * \param[in] s the udp max size
+ */
+void ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s);
+
+/**
+ * Set the tsig key name
+ * \param[in] r the resolver
+ * \param[in] tsig_keyname the tsig key name
+ */
+void ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname);
+
+/**
+ * Set the tsig algorithm
+ * \param[in] r the resolver
+ * \param[in] tsig_algorithm the tsig algorithm
+ */
+void ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm);
+
+/**
+ * Set the tsig key data
+ * \param[in] r the resolver
+ * \param[in] tsig_keydata the key data
+ */
+void ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata);
+
+/**
+ * Set round trip time for all nameservers. Note this currently
+ * differentiates between: unreachable and reachable.
+ * \param[in] r the resolver
+ * \param[in] rtt a list with the times
+ */
+void ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt);
+
+/**
+ * Set round trip time for a specific nameserver. Note this
+ * currently differentiates between: unreachable and reachable.
+ * \param[in] r the resolver
+ * \param[in] pos the nameserver position
+ * \param[in] value the rtt
+ */
+void ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value);
+
+/**
+ * Should the nameserver list be randomized before each use
+ * \param[in] r the resolver
+ * \param[in] b: true: randomize, false: don't
+ */
+void ldns_resolver_set_random(ldns_resolver *r, bool b);
+
+/**
+ * Push a new nameserver to the resolver. It must be an IP
+ * address v4 or v6.
+ * \param[in] r the resolver
+ * \param[in] n the ip address
+ * \return ldns_status a status
+ */
+ldns_status ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n);
+
+/**
+ * Push a new nameserver to the resolver. It must be an
+ * A or AAAA RR record type
+ * \param[in] r the resolver
+ * \param[in] rr the resource record
+ * \return ldns_status a status
+ */
+ldns_status ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr);
+
+/**
+ * Push a new nameserver rr_list to the resolver.
+ * \param[in] r the resolver
+ * \param[in] rrlist the rr_list to push
+ * \return ldns_status a status
+ */
+ldns_status ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list *rrlist);
+
+/**
+ * Send the query for using the resolver and take the search list into account
+ * The search algorithm is as follows:
+ * If the name is absolute, try it as-is, otherwise apply the search list
+ * \param[in] *r operate using this resolver
+ * \param[in] *rdf query for this name
+ * \param[in] t query for this type (may be 0, defaults to A)
+ * \param[in] c query for this class (may be 0, default to IN)
+ * \param[in] flags the query flags
+ *
+ * \return ldns_pkt* a packet with the reply from the nameserver
+ */
+ldns_pkt* ldns_resolver_search(const ldns_resolver *r, const ldns_rdf *rdf, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
+
+
+/**
+ * Send the query for using the resolver and take the search list into account
+ * The search algorithm is as follows:
+ * If the name is absolute, try it as-is, otherwise apply the search list
+ * \param[out] pkt a packet with the reply from the nameserver
+ * \param[in] *r operate using this resolver
+ * \param[in] *rdf query for this name
+ * \param[in] t query for this type (may be 0, defaults to A)
+ * \param[in] c query for this class (may be 0, default to IN)
+ * \param[in] flags the query flags
+ *
+ * \return ldns_status LDNS_STATUS_OK on success
+ */
+ldns_status ldns_resolver_search_status(ldns_pkt** pkt, ldns_resolver *r, const ldns_rdf *rdf, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
+
+/**
+ * Form a query packet from a resolver and name/type/class combo
+ * \param[out] **q a pointer to a ldns_pkt pointer (initialized by this function)
+ * \param[in] *r operate using this resolver
+ * \param[in] *name query for this name
+ * \param[in] t query for this type (may be 0, defaults to A)
+ * \param[in] c query for this class (may be 0, default to IN)
+ * \param[in] f the query flags
+ *
+ * \return ldns_pkt* a packet with the reply from the nameserver
+ */
+ldns_status ldns_resolver_prepare_query_pkt(ldns_pkt **q, ldns_resolver *r, const  ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t f);
+
+/**
+ * Send the query for name as-is
+ * \param[out] **answer a pointer to a ldns_pkt pointer (initialized by this function)
+ * \param[in] *r operate using this resolver
+ * \param[in] *name query for this name
+ * \param[in] t query for this type (may be 0, defaults to A)
+ * \param[in] c query for this class (may be 0, default to IN)
+ * \param[in] flags the query flags
+ *
+ * \return ldns_pkt* a packet with the reply from the nameserver
+ */
+ldns_status ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
+
+/**
+ * Send the given packet to a nameserver
+ * \param[out] **answer a pointer to a ldns_pkt pointer (initialized by this function)
+ * \param[in] *r operate using this resolver
+ * \param[in] *query_pkt query
+ */
+ldns_status ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, ldns_pkt *query_pkt);
+
+/**
+ * Send a query to a nameserver
+ * \param[out] pkt a packet with the reply from the nameserver
+ * \param[in] *r operate using this resolver
+ * \param[in] *name query for this name
+ * \param[in] *t query for this type (may be 0, defaults to A)
+ * \param[in] *c query for this class (may be 0, default to IN)
+ * \param[in] flags the query flags
+ *
+ * \return ldns_status LDNS_STATUS_OK on success
+ * if _defnames is true the default domain will be added
+ */
+ldns_status ldns_resolver_query_status(ldns_pkt** pkt, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
+
+
+/**
+ * Send a query to a nameserver
+ * \param[in] *r operate using this resolver 
+ *               (despite the const in the declaration,
+ *                the struct is altered as a side-effect)
+ * \param[in] *name query for this name
+ * \param[in] *t query for this type (may be 0, defaults to A)
+ * \param[in] *c query for this class (may be 0, default to IN)
+ * \param[in] flags the query flags
+ *
+ * \return ldns_pkt* a packet with the reply from the nameserver
+ * if _defnames is true the default domain will be added
+ */
+ldns_pkt* ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags);
+
+
+/**
+ * Create a new resolver structure
+ * \return ldns_resolver* pointer to new structure
+ */
+ldns_resolver* ldns_resolver_new(void);
+
+/**
+ * Clone a resolver
+ * \param[in] r the resolver to clone
+ * \return ldns_resolver* pointer to new structure
+ */
+ldns_resolver* ldns_resolver_clone(ldns_resolver *r);
+
+/**
+ * Create a resolver structure from a file like /etc/resolv.conf
+ * \param[out] r the new resolver
+ * \param[in] fp file pointer to create new resolver from
+ *      if NULL use /etc/resolv.conf
+ * \return LDNS_STATUS_OK or the error
+ */
+ldns_status ldns_resolver_new_frm_fp(ldns_resolver **r, FILE *fp);
+
+/**
+ * Create a resolver structure from a file like /etc/resolv.conf
+ * \param[out] r the new resolver
+ * \param[in] fp file pointer to create new resolver from
+ *      if NULL use /etc/resolv.conf
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return LDNS_STATUS_OK or the error
+ */
+ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **r, FILE *fp, int *line_nr);
+
+/**
+ * Configure a resolver by means of a resolv.conf file
+ * The file may be NULL in which case there will  be
+ * looked the RESOLV_CONF (defaults to /etc/resolv.conf
+ * \param[out] r the new resolver
+ * \param[in] filename the filename to use
+ * \return LDNS_STATUS_OK or the error
+ */
+ldns_status ldns_resolver_new_frm_file(ldns_resolver **r, const char *filename);
+
+/**
+ * Frees the allocated space for this resolver. Only frees the resolver pionter! You should probably be using _deep_free.
+ * \param res resolver to free
+ */
+void ldns_resolver_free(ldns_resolver *res);
+
+/**
+ * Frees the allocated space for this resolver and all it's data
+ * \param res resolver to free
+ */
+void ldns_resolver_deep_free(ldns_resolver *res);
+
+/**
+ * Get the next stream of RRs in a AXFR
+ * \param[in] resolver the resolver to use. First ldns_axfr_start() must be
+ * called
+ * \return ldns_rr the next RR from the AXFR stream
+ * After you get this returned RR (not NULL: on error), then check if 
+ * ldns_axfr_complete() is true to see if the zone transfer has completed.
+ */
+ldns_rr* ldns_axfr_next(ldns_resolver *resolver);
+
+/**
+ * Abort a transfer that is in progress
+ * \param[in] resolver the resolver that is used
+ */
+void ldns_axfr_abort(ldns_resolver *resolver);
+
+/**
+ * Returns true if the axfr transfer has completed (i.e. 2 SOA RRs and no errors were encountered
+ * \param[in] resolver the resolver that is used
+ * \return bool true if axfr transfer was completed without error
+ */
+bool ldns_axfr_complete(const ldns_resolver *resolver);
+
+/**
+ * Returns a pointer to the last ldns_pkt that was sent by the server in the AXFR transfer
+ * uasable for instance to get the error code on failure
+ * \param[in] res the resolver that was used in the axfr transfer
+ * \return ldns_pkt the last packet sent
+ */
+ldns_pkt *ldns_axfr_last_pkt(const ldns_resolver *res);
+
+/**
+ * Get the serial for requesting IXFR.
+ * \param[in] r the resolver
+ * \param[in] serial serial
+ */
+void ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial);
+
+/**
+ * Get the serial for requesting IXFR.
+ * \param[in] res the resolver
+ * \return uint32_t serial
+ */
+uint32_t ldns_resolver_get_ixfr_serial(const ldns_resolver *res);
+
+/**
+ * Randomize the nameserver list in the resolver
+ * \param[in] r the resolver
+ */
+void ldns_resolver_nameservers_randomize(ldns_resolver *r);
+
+/**
+ * Returns true if at least one of the provided keys is a trust anchor
+ * \param[in] r the current resolver
+ * \param[in] keys the keyset to check
+ * \param[out] trusted_keys the subset of trusted keys in the 'keys' rrset
+ * \return true if at least one of the provided keys is a configured trust anchor
+ */
+bool ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* LDNS_RESOLVER_H */
diff --git a/ldns/include/ldns/rr.h b/ldns/include/ldns/rr.h
new file mode 100644
index 0000000..75ac352
--- /dev/null
+++ b/ldns/include/ldns/rr.h
@@ -0,0 +1,929 @@
+/*
+ * rr.h -  resource record definitions
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file
+ *
+ * Contains the definition of ldns_rr and functions to manipulate those.
+ */
+
+
+#ifndef LDNS_RR_H
+#define LDNS_RR_H
+
+#include <ldns/common.h>
+#include <ldns/rdata.h>
+#include <ldns/buffer.h>
+#include <ldns/error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Maximum length of a dname label */
+#define LDNS_MAX_LABELLEN     63
+/** Maximum length of a complete dname */
+#define LDNS_MAX_DOMAINLEN    255
+/** Maximum number of pointers in 1 dname */
+#define LDNS_MAX_POINTERS	65535
+/** The bytes TTL, CLASS and length use up in an rr */
+#define LDNS_RR_OVERHEAD	10
+
+/* The first fields are contiguous and can be referenced instantly */
+#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON 258
+
+
+
+/**
+ *  The different RR classes.
+ */
+enum ldns_enum_rr_class
+{
+	/** the Internet */
+	LDNS_RR_CLASS_IN 	= 1,
+	/** Chaos class */
+	LDNS_RR_CLASS_CH	= 3,
+	/** Hesiod (Dyer 87) */
+	LDNS_RR_CLASS_HS	= 4,
+    /** None class, dynamic update */
+    LDNS_RR_CLASS_NONE      = 254,
+	/** Any class */
+	LDNS_RR_CLASS_ANY	= 255,
+
+	LDNS_RR_CLASS_FIRST     = 0,
+	LDNS_RR_CLASS_LAST      = 65535,
+	LDNS_RR_CLASS_COUNT     = LDNS_RR_CLASS_LAST - LDNS_RR_CLASS_FIRST + 1
+};
+typedef enum ldns_enum_rr_class ldns_rr_class;
+
+/**
+ *  Used to specify whether compression is allowed.
+ */
+enum ldns_enum_rr_compress
+{
+	/** compression is allowed */
+	LDNS_RR_COMPRESS,
+	LDNS_RR_NO_COMPRESS
+};
+typedef enum ldns_enum_rr_compress ldns_rr_compress;
+
+/**
+ * The different RR types.
+ */
+enum ldns_enum_rr_type
+{
+	/**  a host address */
+	LDNS_RR_TYPE_A = 1,
+	/**  an authoritative name server */
+	LDNS_RR_TYPE_NS = 2,
+	/**  a mail destination (Obsolete - use MX) */
+	LDNS_RR_TYPE_MD = 3,
+	/**  a mail forwarder (Obsolete - use MX) */
+	LDNS_RR_TYPE_MF = 4,
+	/**  the canonical name for an alias */
+	LDNS_RR_TYPE_CNAME = 5,
+	/**  marks the start of a zone of authority */
+	LDNS_RR_TYPE_SOA = 6,
+	/**  a mailbox domain name (EXPERIMENTAL) */
+	LDNS_RR_TYPE_MB = 7,
+	/**  a mail group member (EXPERIMENTAL) */
+	LDNS_RR_TYPE_MG = 8,
+	/**  a mail rename domain name (EXPERIMENTAL) */
+	LDNS_RR_TYPE_MR = 9,
+	/**  a null RR (EXPERIMENTAL) */
+	LDNS_RR_TYPE_NULL = 10,
+	/**  a well known service description */
+	LDNS_RR_TYPE_WKS = 11,
+	/**  a domain name pointer */
+	LDNS_RR_TYPE_PTR = 12,
+	/**  host information */
+	LDNS_RR_TYPE_HINFO = 13,
+	/**  mailbox or mail list information */
+	LDNS_RR_TYPE_MINFO = 14,
+	/**  mail exchange */
+	LDNS_RR_TYPE_MX = 15,
+	/**  text strings */
+	LDNS_RR_TYPE_TXT = 16,
+	/**  RFC1183 */
+	LDNS_RR_TYPE_RP = 17,
+	/**  RFC1183 */
+	LDNS_RR_TYPE_AFSDB = 18,
+	/**  RFC1183 */
+	LDNS_RR_TYPE_X25 = 19,
+	/**  RFC1183 */
+	LDNS_RR_TYPE_ISDN = 20,
+	/**  RFC1183 */
+	LDNS_RR_TYPE_RT = 21,
+	/**  RFC1706 */
+	LDNS_RR_TYPE_NSAP = 22,
+	/**  RFC1348 */
+	LDNS_RR_TYPE_NSAP_PTR = 23,
+	/**  2535typecode */
+	LDNS_RR_TYPE_SIG = 24,
+	/**  2535typecode */
+	LDNS_RR_TYPE_KEY = 25,
+	/**  RFC2163 */
+	LDNS_RR_TYPE_PX = 26,
+	/**  RFC1712 */
+	LDNS_RR_TYPE_GPOS = 27,
+	/**  ipv6 address */
+	LDNS_RR_TYPE_AAAA = 28,
+	/**  LOC record  RFC1876 */
+	LDNS_RR_TYPE_LOC = 29,
+	/**  2535typecode */
+	LDNS_RR_TYPE_NXT = 30,
+	/**  draft-ietf-nimrod-dns-01.txt */
+	LDNS_RR_TYPE_EID = 31,
+	/**  draft-ietf-nimrod-dns-01.txt */
+	LDNS_RR_TYPE_NIMLOC = 32,
+	/**  SRV record RFC2782 */
+	LDNS_RR_TYPE_SRV = 33,
+	/**  http://www.jhsoft.com/rfc/af-saa-0069.000.rtf */
+	LDNS_RR_TYPE_ATMA = 34,
+	/**  RFC2915 */
+	LDNS_RR_TYPE_NAPTR = 35,
+	/**  RFC2230 */
+	LDNS_RR_TYPE_KX = 36,
+	/**  RFC2538 */
+	LDNS_RR_TYPE_CERT = 37,
+	/**  RFC2874 */
+	LDNS_RR_TYPE_A6 = 38,
+	/**  RFC2672 */
+	LDNS_RR_TYPE_DNAME = 39,
+	/**  dnsind-kitchen-sink-02.txt */
+	LDNS_RR_TYPE_SINK = 40,
+	/**  Pseudo OPT record... */
+	LDNS_RR_TYPE_OPT = 41,
+	/**  RFC3123 */
+	LDNS_RR_TYPE_APL = 42,
+	/**  RFC4034, RFC3658 */
+	LDNS_RR_TYPE_DS = 43,
+	/**  SSH Key Fingerprint */
+	LDNS_RR_TYPE_SSHFP = 44, /* RFC 4255 */
+	/**  IPsec Key */
+	LDNS_RR_TYPE_IPSECKEY = 45, /* RFC 4025 */
+	/**  DNSSEC */
+	LDNS_RR_TYPE_RRSIG = 46, /* RFC 4034 */
+	LDNS_RR_TYPE_NSEC = 47, /* RFC 4034 */
+	LDNS_RR_TYPE_DNSKEY = 48, /* RFC 4034 */
+
+	LDNS_RR_TYPE_DHCID = 49, /* RFC 4701 */
+	/* NSEC3 */
+	LDNS_RR_TYPE_NSEC3 = 50, /* RFC 5155 */
+	LDNS_RR_TYPE_NSEC3PARAM = 51, /* RFC 5155 */
+	LDNS_RR_TYPE_NSEC3PARAMS = 51,
+	LDNS_RR_TYPE_TLSA = 52, /* RFC 6698 */
+
+	LDNS_RR_TYPE_HIP = 55, /* RFC 5205 */
+
+	/** draft-reid-dnsext-zs */
+	LDNS_RR_TYPE_NINFO = 56,
+	/** draft-reid-dnsext-rkey */
+	LDNS_RR_TYPE_RKEY = 57,
+        /** draft-ietf-dnsop-trust-history */
+        LDNS_RR_TYPE_TALINK = 58,
+	LDNS_RR_TYPE_CDS = 59, /* RFC 7344 */
+	LDNS_RR_TYPE_CDNSKEY = 60, /* RFC 7344 */
+	/** draft-ietf-dane-openpgpkey */
+	LDNS_RR_TYPE_OPENPGPKEY = 61,
+
+	LDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
+
+	LDNS_RR_TYPE_UINFO = 100,
+	LDNS_RR_TYPE_UID = 101,
+	LDNS_RR_TYPE_GID = 102,
+	LDNS_RR_TYPE_UNSPEC = 103,
+
+	LDNS_RR_TYPE_NID = 104, /* RFC 6742 */
+	LDNS_RR_TYPE_L32 = 105, /* RFC 6742 */
+	LDNS_RR_TYPE_L64 = 106, /* RFC 6742 */
+	LDNS_RR_TYPE_LP = 107, /* RFC 6742 */
+
+	LDNS_RR_TYPE_EUI48 = 108, /* RFC 7043 */
+	LDNS_RR_TYPE_EUI64 = 109, /* RFC 7043 */
+
+	LDNS_RR_TYPE_TKEY = 249, /* RFC 2930 */
+	LDNS_RR_TYPE_TSIG = 250,
+	LDNS_RR_TYPE_IXFR = 251,
+	LDNS_RR_TYPE_AXFR = 252,
+	/**  A request for mailbox-related records (MB, MG or MR) */
+	LDNS_RR_TYPE_MAILB = 253,
+	/**  A request for mail agent RRs (Obsolete - see MX) */
+	LDNS_RR_TYPE_MAILA = 254,
+	/**  any type (wildcard) */
+	LDNS_RR_TYPE_ANY = 255,
+	/** draft-faltstrom-uri-06 */
+	LDNS_RR_TYPE_URI = 256,
+	LDNS_RR_TYPE_CAA = 257, /* RFC 6844 */
+
+	/** DNSSEC Trust Authorities */
+	LDNS_RR_TYPE_TA = 32768,
+	/* RFC 4431, 5074, DNSSEC Lookaside Validation */
+	LDNS_RR_TYPE_DLV = 32769,
+
+	/* type codes from nsec3 experimental phase
+	LDNS_RR_TYPE_NSEC3 = 65324,
+	LDNS_RR_TYPE_NSEC3PARAMS = 65325, */
+	LDNS_RR_TYPE_FIRST = 0,
+	LDNS_RR_TYPE_LAST  = 65535,
+	LDNS_RR_TYPE_COUNT = LDNS_RR_TYPE_LAST - LDNS_RR_TYPE_FIRST + 1
+};
+typedef enum ldns_enum_rr_type ldns_rr_type;
+
+/**
+ * Resource Record
+ *
+ * This is the basic DNS element that contains actual data
+ *
+ * From RFC1035:
+ * <pre>
+3.2.1. Format
+
+All RRs have the same top level format shown below:
+
+                                    1  1  1  1  1  1
+      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                                               |
+    /                                               /
+    /                      NAME                     /
+    |                                               |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                      TYPE                     |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                     CLASS                     |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                      TTL                      |
+    |                                               |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+    |                   RDLENGTH                    |
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
+    /                     RDATA                     /
+    /                                               /
+    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
+where:
+
+NAME            an owner name, i.e., the name of the node to which this
+                resource record pertains.
+
+TYPE            two octets containing one of the RR TYPE codes.
+
+CLASS           two octets containing one of the RR CLASS codes.
+
+TTL             a 32 bit signed integer that specifies the time interval
+                that the resource record may be cached before the source
+                of the information should again be consulted.  Zero
+                values are interpreted to mean that the RR can only be
+                used for the transaction in progress, and should not be
+                cached.  For example, SOA records are always distributed
+                with a zero TTL to prohibit caching.  Zero values can
+                also be used for extremely volatile data.
+
+RDLENGTH        an unsigned 16 bit integer that specifies the length in
+                octets of the RDATA field.
+
+RDATA           a variable length string of octets that describes the
+                resource.  The format of this information varies
+                according to the TYPE and CLASS of the resource record.
+ * </pre>
+ *
+ * The actual amount and type of rdata fields depend on the RR type of the
+ * RR, and can be found by using \ref ldns_rr_descriptor functions.
+ */
+struct ldns_struct_rr
+{
+	/**  Owner name, uncompressed */
+	ldns_rdf	*_owner;
+	/**  Time to live  */
+	uint32_t	_ttl;
+	/**  Number of data fields */
+	size_t	        _rd_count;
+	/**  the type of the RR. A, MX etc. */
+	ldns_rr_type	_rr_type;
+	/**  Class of the resource record.  */
+	ldns_rr_class	_rr_class;
+	/* everything in the rdata is in network order */
+	/**  The array of rdata's */
+	ldns_rdf	 **_rdata_fields;
+	/**  question rr [it would be nicer if thous is after _rd_count]
+		 ABI change: Fix this in next major release
+	 */
+	bool		_rr_question;
+};
+typedef struct ldns_struct_rr ldns_rr;
+
+/**
+ * List or Set of Resource Records
+ *
+ * Contains a list of rr's <br>
+ * No official RFC-like checks are made
+ */
+struct ldns_struct_rr_list
+{
+	size_t _rr_count;
+	size_t _rr_capacity;
+	ldns_rr **_rrs;
+};
+typedef struct ldns_struct_rr_list ldns_rr_list;
+
+/**
+ * Contains all information about resource record types.
+ *
+ * This structure contains, for all rr types, the rdata fields that are defined.
+ */
+struct ldns_struct_rr_descriptor
+{
+	/** Type of the RR that is described here */
+	ldns_rr_type    _type;
+	/** Textual name of the RR type.  */
+	const char *_name;
+	/** Minimum number of rdata fields in the RRs of this type.  */
+	uint8_t     _minimum;
+	/** Maximum number of rdata fields in the RRs of this type.  */
+	uint8_t     _maximum;
+	/** Wireformat specification for the rr, i.e. the types of rdata fields in their respective order. */
+	const ldns_rdf_type *_wireformat;
+	/** Special rdf types */
+	ldns_rdf_type _variable;
+	/** Specifies whether compression can be used for dnames in this RR type. */
+	ldns_rr_compress _compress;
+	/** The number of DNAMEs in the _wireformat string, for parsing. */
+	uint8_t _dname_count;
+};
+typedef struct ldns_struct_rr_descriptor ldns_rr_descriptor;
+
+
+/**
+ * Create a rr type bitmap rdf providing enough space to set all 
+ * known (to ldns) rr types.
+ * \param[out] rdf the constructed rdf
+ * \return LDNS_STATUS_OK if all went well.
+ */
+ldns_status ldns_rdf_bitmap_known_rr_types_space(ldns_rdf** rdf);
+
+/**
+ * Create a rr type bitmap rdf with at least all known (to ldns) rr types set.
+ * \param[out] rdf the constructed rdf
+ * \return LDNS_STATUS_OK if all went well.
+ */
+ldns_status ldns_rdf_bitmap_known_rr_types(ldns_rdf** rdf);
+
+
+/**
+ * creates a new rr structure.
+ * \return ldns_rr *
+ */
+ldns_rr* ldns_rr_new(void);
+
+/**
+ * creates a new rr structure, based on the given type.
+ * alloc enough space to hold all the rdf's
+ */
+ldns_rr* ldns_rr_new_frm_type(ldns_rr_type t);
+
+/**
+ * frees an RR structure
+ * \param[in] *rr the RR to be freed
+ * \return void
+ */
+void ldns_rr_free(ldns_rr *rr);
+
+/**
+ * creates an rr from a string.
+ * The string should be a fully filled-in rr, like
+ * ownername &lt;space&gt; TTL &lt;space&gt; CLASS &lt;space&gt;
+ * TYPE &lt;space&gt; RDATA.
+ * \param[out] n the rr to return
+ * \param[in] str the string to convert
+ * \param[in] default_ttl default ttl value for the rr.
+ *            If 0 DEF_TTL will be used
+ * \param[in] origin when the owner is relative add this.
+ *	The caller must ldns_rdf_deep_free it.
+ * \param[out] prev the previous ownername. if this value is not NULL,
+ * the function overwrites this with the ownername found in this
+ * string. The caller must then ldns_rdf_deep_free it.
+ * \return a status msg describing an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_rr_new_frm_str(ldns_rr **n, const char *str,
+                                uint32_t default_ttl, ldns_rdf *origin,
+                                ldns_rdf **prev);
+
+/**
+ * creates an rr for the question section from a string, i.e.
+ * without RDATA fields
+ * Origin and previous RR functionality are the same as in
+ * ldns_rr_new_frm_str()
+ * \param[out] n the rr to return
+ * \param[in] str the string to convert
+ * \param[in] origin when the owner is relative add this.
+ *	The caller must ldns_rdf_deep_free it.
+ * \param prev the previous ownername. the function overwrite this with
+ * the current found ownername. The caller must ldns_rdf_deep_free it.
+ * \return a status msg describing an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_rr_new_question_frm_str(ldns_rr **n, const char *str,
+                                ldns_rdf *origin, ldns_rdf **prev);
+
+/**
+ * creates a new rr from a file containing a string.
+ * \param[out] rr the new rr
+ * \param[in] fp the file pointer to use
+ * \param[in] default_ttl pointer to a default ttl for the rr. If NULL DEF_TTL will be used
+ *            the pointer will be updated if the file contains a $TTL directive
+ * \param[in] origin when the owner is relative add this
+ * 	      the pointer will be updated if the file contains a $ORIGIN directive
+ *	      The caller must ldns_rdf_deep_free it.
+ * \param[in] prev when the owner is whitespaces use this as the * ownername
+ *            the pointer will be updated after the call
+ *	      The caller must ldns_rdf_deep_free it.
+ * \return a ldns_status with an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_rr_new_frm_fp(ldns_rr **rr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev);
+
+/**
+ * creates a new rr from a file containing a string.
+ * \param[out] rr the new rr
+ * \param[in] fp the file pointer to use
+ * \param[in] default_ttl a default ttl for the rr. If NULL DEF_TTL will be used
+ *            the pointer will be updated if the file contains a $TTL directive
+ * \param[in] origin when the owner is relative add this
+ * 	      the pointer will be updated if the file contains a $ORIGIN directive
+ *	      The caller must ldns_rdf_deep_free it.
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \param[in] prev when the owner is whitespaces use this as the * ownername
+ *            the pointer will be updated after the call
+ *	      The caller must ldns_rdf_deep_free it.
+ * \return a ldns_status with an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_rr_new_frm_fp_l(ldns_rr **rr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr);
+
+/**
+ * sets the owner in the rr structure.
+ * \param[in] *rr rr to operate on
+ * \param[in] *owner set to this owner
+ * \return void
+ */
+void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner);
+
+/**
+ * sets the question flag in the rr structure.
+ * \param[in] *rr rr to operate on
+ * \param[in] question question flag
+ * \return void
+ */
+void ldns_rr_set_question(ldns_rr *rr, bool question);
+
+/**
+ * sets the ttl in the rr structure.
+ * \param[in] *rr rr to operate on
+ * \param[in] ttl set to this ttl
+ * \return void
+ */
+void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl);
+
+/**
+ * sets the rd_count in the rr.
+ * \param[in] *rr rr to operate on
+ * \param[in] count set to this count
+ * \return void
+ */
+void ldns_rr_set_rd_count(ldns_rr *rr, size_t count);
+
+/**
+ * sets the type in the rr.
+ * \param[in] *rr rr to operate on
+ * \param[in] rr_type set to this type
+ * \return void
+ */
+void ldns_rr_set_type(ldns_rr *rr, ldns_rr_type rr_type);
+
+/**
+ * sets the class in the rr.
+ * \param[in] *rr rr to operate on
+ * \param[in] rr_class set to this class
+ * \return void
+ */
+void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class);
+
+/**
+ * sets a rdf member, it will be set on the
+ * position given. The old value is returned, like pop.
+ * \param[in] *rr the rr to operate on
+ * \param[in] *f the rdf to set
+ * \param[in] position the position the set the rdf
+ * \return  the old value in the rr, NULL on failyre
+ */
+ldns_rdf* ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position);
+
+/**
+ * sets rd_field member, it will be
+ * placed in the next available spot.
+ * \param[in] *rr rr to operate on
+ * \param[in] *f the data field member to set
+ * \return bool
+ */
+bool ldns_rr_push_rdf(ldns_rr *rr, const ldns_rdf *f);
+
+/**
+ * removes a rd_field member, it will be
+ * popped from the last position.
+ * \param[in] *rr rr to operate on
+ * \return rdf which was popped (null if nothing)
+ */
+ldns_rdf* ldns_rr_pop_rdf(ldns_rr *rr);
+
+/**
+ * returns the rdata field member counter.
+ * \param[in] *rr rr to operate on
+ * \param[in] nr the number of the rdf to return
+ * \return ldns_rdf *
+ */
+ldns_rdf* ldns_rr_rdf(const ldns_rr *rr, size_t nr);
+
+/**
+ * returns the owner name of an rr structure.
+ * \param[in] *rr rr to operate on
+ * \return ldns_rdf *
+ */
+ldns_rdf* ldns_rr_owner(const ldns_rr *rr);
+
+/**
+ * returns the question flag of an rr structure.
+ * \param[in] *rr rr to operate on
+ * \return bool true if question
+ */
+bool ldns_rr_is_question(const ldns_rr *rr);
+
+/**
+ * returns the ttl of an rr structure.
+ * \param[in] *rr the rr to read from
+ * \return the ttl of the rr
+ */
+uint32_t ldns_rr_ttl(const ldns_rr *rr);
+
+/**
+ * returns the rd_count of an rr structure.
+ * \param[in] *rr the rr to read from
+ * \return the rd count of the rr
+ */
+size_t ldns_rr_rd_count(const ldns_rr *rr);
+
+/**
+ * returns the type of the rr.
+ * \param[in] *rr the rr to read from
+ * \return the type of the rr
+ */
+ldns_rr_type ldns_rr_get_type(const ldns_rr *rr);
+
+/**
+ * returns the class of the rr.
+ * \param[in] *rr the rr to read from
+ * \return the class of the rr
+ */
+ldns_rr_class ldns_rr_get_class(const ldns_rr *rr);
+
+/* rr_lists */
+
+/**
+ * returns the number of rr's in an rr_list.
+ * \param[in] rr_list  the rr_list to read from
+ * \return the number of rr's
+ */
+size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list);
+
+/**
+ * sets the number of rr's in an rr_list.
+ * \param[in] rr_list the rr_list to set the count on
+ * \param[in] count the number of rr in this list
+ * \return void
+ */
+void ldns_rr_list_set_rr_count(ldns_rr_list *rr_list, size_t count);
+
+/**
+ * set a rr on a specific index in a ldns_rr_list
+ * \param[in] rr_list the rr_list to use
+ * \param[in] r the rr to set
+ * \param[in] count index into the rr_list
+ * \return the old rr which was stored in the rr_list, or
+ * NULL is the index was too large
+ * set a specific rr */
+ldns_rr * ldns_rr_list_set_rr(ldns_rr_list *rr_list, const ldns_rr *r, size_t count);
+
+/**
+ * returns a specific rr of an rrlist.
+ * \param[in] rr_list the rr_list to read from
+ * \param[in] nr return this rr
+ * \return the rr at position nr
+ */
+ldns_rr* ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr);
+
+/**
+ * creates a new rr_list structure.
+ * \return a new rr_list structure
+ */
+ldns_rr_list* ldns_rr_list_new(void);
+
+/**
+ * frees an rr_list structure.
+ * \param[in] rr_list the list to free
+ */
+void ldns_rr_list_free(ldns_rr_list *rr_list);
+
+/**
+ * frees an rr_list structure and all rrs contained therein.
+ * \param[in] rr_list the list to free
+ */
+void ldns_rr_list_deep_free(ldns_rr_list *rr_list);
+
+/**
+ * concatenates two ldns_rr_lists together. This modifies
+ * *left (to extend it and add the pointers from *right).
+ * \param[in] left the leftside
+ * \param[in] right the rightside
+ * \return a left with right concatenated to it
+ */
+bool ldns_rr_list_cat(ldns_rr_list *left, ldns_rr_list *right);
+
+/**
+ * concatenates two ldns_rr_lists together, but makes clones of the rr's 
+ * (instead of pointer copying).
+ * \param[in] left the leftside
+ * \param[in] right the rightside
+ * \return a new rr_list with leftside/rightside concatenated
+ */
+ldns_rr_list* ldns_rr_list_cat_clone(ldns_rr_list *left, ldns_rr_list *right);
+
+/**
+ * pushes an rr to an rrlist.
+ * \param[in] rr_list the rr_list to push to 
+ * \param[in] rr the rr to push 
+ * \return false on error, otherwise true
+ */
+bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr);
+
+/**
+ * pushes an rr_list to an rrlist.
+ * \param[in] rr_list the rr_list to push to 
+ * \param[in] push_list the rr_list to push 
+ * \return false on error, otherwise true
+ */
+bool ldns_rr_list_push_rr_list(ldns_rr_list *rr_list, const ldns_rr_list *push_list);
+
+/**
+ * pops the last rr from an rrlist.
+ * \param[in] rr_list the rr_list to pop from
+ * \return NULL if nothing to pop. Otherwise the popped RR
+ */
+ldns_rr* ldns_rr_list_pop_rr(ldns_rr_list *rr_list);
+
+/**
+ * pops an  rr_list of size s from an rrlist.
+ * \param[in] rr_list the rr_list to pop from
+ * \param[in] size the number of rr's to pop 
+ * \return NULL if nothing to pop. Otherwise the popped rr_list
+ */
+ldns_rr_list* ldns_rr_list_pop_rr_list(ldns_rr_list *rr_list, size_t size);
+
+/**
+ * returns true if the given rr is one of the rrs in the
+ * list, or if it is equal to one
+ * \param[in] rr_list the rr_list to check
+ * \param[in] rr the rr to check
+ * \return true if rr_list contains rr, false otherwise
+ */
+bool ldns_rr_list_contains_rr(const ldns_rr_list *rr_list, ldns_rr *rr); 
+
+/**
+ * checks if an rr_list is a rrset.
+ * \param[in] rr_list the rr_list to check
+ * \return true if it is an rrset otherwise false
+ */
+bool ldns_is_rrset(ldns_rr_list *rr_list);
+
+/**
+ * pushes an rr to an rrset (which really are rr_list's).
+ * \param[in] *rr_list the rrset to push the rr to
+ * \param[in] *rr the rr to push
+ * \return true if the push succeeded otherwise false
+ */
+bool ldns_rr_set_push_rr(ldns_rr_list *rr_list, ldns_rr *rr);
+
+/**
+ * pops the last rr from an rrset. This function is there only
+ * for the symmetry.
+ * \param[in] rr_list the rr_list to pop from
+ * \return NULL if nothing to pop. Otherwise the popped RR
+ *
+ */
+ldns_rr* ldns_rr_set_pop_rr(ldns_rr_list *rr_list);
+
+/**
+ * pops the first rrset from the list,
+ * the list must be sorted, so that all rr's from each rrset
+ * are next to each other
+ */
+ldns_rr_list *ldns_rr_list_pop_rrset(ldns_rr_list *rr_list);
+
+
+/**
+ * retrieves a rrtype by looking up its name.
+ * \param[in] name a string with the name
+ * \return the type which corresponds with the name
+ */
+ldns_rr_type ldns_get_rr_type_by_name(const char *name);
+
+/**
+ * retrieves a class by looking up its name.
+ * \param[in] name string with the name
+ * \return the cass which corresponds with the name
+ */
+ldns_rr_class ldns_get_rr_class_by_name(const char *name);
+
+/**
+ * clones a rr and all its data
+ * \param[in] rr the rr to clone
+ * \return the new rr or NULL on failure
+ */
+ldns_rr* ldns_rr_clone(const ldns_rr *rr);
+
+/**
+ * clones an rrlist.
+ * \param[in] rrlist the rrlist to clone
+ * \return the cloned rr list
+ */
+ldns_rr_list* ldns_rr_list_clone(const ldns_rr_list *rrlist);
+
+/**
+ * sorts an rr_list (canonical wire format). the sorting is done inband.
+ * \param[in] unsorted the rr_list to be sorted
+ * \return void
+ */
+void ldns_rr_list_sort(ldns_rr_list *unsorted);
+
+/**
+ * compares two rrs. The TTL is not looked at.
+ * \param[in] rr1 the first one
+ * \param[in] rr2 the second one
+ * \return 0 if equal
+ *         -1 if rr1 comes before rr2
+ *         +1 if rr2 comes before rr1
+ */
+int ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2);
+
+/**
+ * compares two rrs, up to the rdata.
+ * \param[in] rr1 the first one
+ * \param[in] rr2 the second one
+ * \return 0 if equal
+ *         -1 if rr1 comes before rr2
+ *         +1 if rr2 comes before rr1
+ */
+int ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2);
+
+/**
+ * compares the wireformat of two rrs, contained in the given buffers.
+ * \param[in] rr1_buf the first one
+ * \param[in] rr2_buf the second one
+ * \return 0 if equal
+ *         -1 if rr1_buf comes before rr2_buf
+ *         +1 if rr2_buf comes before rr1_buf
+ */
+int ldns_rr_compare_wire(ldns_buffer *rr1_buf, ldns_buffer *rr2_buf);
+
+/**
+ * returns true of the given rr's are equal.
+ * Also returns true if one record is a DS that represents the
+ * same DNSKEY record as the other record
+ * \param[in] rr1 the first rr
+ * \param[in] rr2 the second rr
+ * \return true if equal otherwise false
+ */
+bool ldns_rr_compare_ds(const ldns_rr *rr1, const ldns_rr *rr2);
+
+/**
+ * compares two rr listss.
+ * \param[in] rrl1 the first one
+ * \param[in] rrl2 the second one
+ * \return 0 if equal
+ *         -1 if rrl1 comes before rrl2
+ *         +1 if rrl2 comes before rrl1
+ */
+int ldns_rr_list_compare(const ldns_rr_list *rrl1, const ldns_rr_list *rrl2);
+
+/** 
+ * calculates the uncompressed size of an RR.
+ * \param[in] r the rr to operate on
+ * \return size of the rr
+ */
+size_t ldns_rr_uncompressed_size(const ldns_rr *r);
+
+/** 
+ * converts each dname in a rr to its canonical form.
+ * \param[in] rr the rr to work on
+ * \return void
+ */
+void ldns_rr2canonical(ldns_rr *rr);
+
+/** 
+ * converts each dname in each rr in a rr_list to its canonical form.
+ * \param[in] rr_list the rr_list to work on
+ * \return void
+ */
+void ldns_rr_list2canonical(ldns_rr_list *rr_list);
+
+/** 
+ * counts the number of labels of the ownername.
+ * \param[in] rr count the labels of this rr
+ * \return the number of labels
+ */
+uint8_t ldns_rr_label_count(ldns_rr *rr);
+
+/**
+ * returns the resource record descriptor for the given rr type.
+ *
+ * \param[in] type the type value of the rr type
+ *\return the ldns_rr_descriptor for this type
+ */
+const ldns_rr_descriptor *ldns_rr_descript(uint16_t type);
+
+/**
+ * returns the minimum number of rdata fields of the rr type this descriptor describes.
+ *
+ * \param[in]  descriptor for an rr type
+ * \return the minimum number of rdata fields
+ */
+size_t ldns_rr_descriptor_minimum(const ldns_rr_descriptor *descriptor);
+
+/**
+ * returns the maximum number of rdata fields of the rr type this descriptor describes.
+ *
+ * \param[in]  descriptor for an rr type
+ * \return the maximum number of rdata fields
+ */
+size_t ldns_rr_descriptor_maximum(const ldns_rr_descriptor *descriptor);
+
+/**
+ * returns the rdf type for the given rdata field number of the rr type for the given descriptor.
+ *
+ * \param[in] descriptor for an rr type
+ * \param[in] field the field number
+ * \return the rdf type for the field
+ */
+ldns_rdf_type ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor, size_t field);
+
+/**
+ * Return the rr_list which matches the rdf at position field. Think
+ * type-covered stuff for RRSIG
+ * 
+ * \param[in] l the rr_list to look in
+ * \param[in] r the rdf to use for the comparison
+ * \param[in] pos at which position can we find the rdf
+ * 
+ * \return a new rr list with only the RRs that match 
+ *
+ */
+ldns_rr_list *ldns_rr_list_subtype_by_rdf(ldns_rr_list *l, ldns_rdf *r, size_t pos);
+
+/**
+ * convert an rdf of type LDNS_RDF_TYPE_TYPE to an actual
+ * LDNS_RR_TYPE. This is usefull in the case when inspecting
+ * the rrtype covered field of an RRSIG.
+ * \param[in] rd the rdf to look at
+ * \return a ldns_rr_type with equivalent LDNS_RR_TYPE
+ *
+ */
+ldns_rr_type    ldns_rdf2rr_type(const ldns_rdf *rd);
+
+/**
+ * Returns the type of the first element of the RR
+ * If there are no elements present, 0 is returned
+ * 
+ * \param[in] rr_list The rr list
+ * \return rr_type of the first element, or 0 if the list is empty
+ */
+ldns_rr_type
+ldns_rr_list_type(const ldns_rr_list *rr_list);
+
+/**
+ * Returns the owner domain name rdf of the first element of the RR
+ * If there are no elements present, NULL is returned
+ * 
+ * \param[in] rr_list The rr list
+ * \return dname of the first element, or NULL if the list is empty
+ */
+ldns_rdf *
+ldns_rr_list_owner(const ldns_rr_list *rr_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_RR_H */
diff --git a/ldns/include/ldns/rr_functions.h b/ldns/include/ldns/rr_functions.h
new file mode 100644
index 0000000..09a28dd
--- /dev/null
+++ b/ldns/include/ldns/rr_functions.h
@@ -0,0 +1,363 @@
+/*
+ * rr_functions.h
+ *
+ * the .h file with defs for the per rr
+ * functions
+ *
+ * a Net::DNS like library for C
+ * 
+ * (c) NLnet Labs, 2005-2006
+ * 
+ * See the file LICENSE for the license
+ */
+#ifndef LDNS_RR_FUNCTIONS_H
+#define LDNS_RR_FUNCTIONS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \file
+ *
+ * Defines some extra convenience functions for ldns_rr structures
+ */
+
+/* A / AAAA */
+/**
+ * returns the address of a LDNS_RR_TYPE_A rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the address or NULL on failure
+ */
+ldns_rdf* ldns_rr_a_address(const ldns_rr *r);
+
+/**
+ * sets the address of a LDNS_RR_TYPE_A rr
+ * \param[in] r the rr to use
+ * \param[in] f the address to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f);
+
+/* NS */
+/**
+ * returns the name of a LDNS_RR_TYPE_NS rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the name or NULL on failure
+ */
+ldns_rdf* ldns_rr_ns_nsdname(const ldns_rr *r);
+
+/* MX */
+/**
+ * returns the mx pref. of a LDNS_RR_TYPE_MX rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the preference or NULL on failure
+ */
+ldns_rdf* ldns_rr_mx_preference(const ldns_rr *r);
+/**
+ * returns the mx host of a LDNS_RR_TYPE_MX rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the name of the MX host or NULL on failure
+ */
+ldns_rdf* ldns_rr_mx_exchange(const ldns_rr *r);
+
+/* RRSIG */
+/**
+ * returns the type covered of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the type covered or NULL on failure
+ */
+ldns_rdf* ldns_rr_rrsig_typecovered(const ldns_rr *r);
+/**
+ * sets the typecovered of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the typecovered to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the algorithm of a LDNS_RR_TYPE_RRSIG RR
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the algorithm or NULL on failure
+ */
+ldns_rdf* ldns_rr_rrsig_algorithm(const ldns_rr *r);
+/**
+ * sets the algorithm of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the algorithm to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the number of labels of a LDNS_RR_TYPE_RRSIG RR
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the number of labels or NULL on failure
+ */
+ldns_rdf *ldns_rr_rrsig_labels(const ldns_rr *r);
+/**
+ * sets the number of labels of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the number of labels to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the original TTL of a LDNS_RR_TYPE_RRSIG RR
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the original TTL or NULL on failure
+ */
+ldns_rdf* ldns_rr_rrsig_origttl(const ldns_rr *r);
+/**
+ * sets the original TTL of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the original TTL to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the expiration time of a LDNS_RR_TYPE_RRSIG RR
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the expiration time or NULL on failure
+ */
+ldns_rdf* ldns_rr_rrsig_expiration(const ldns_rr *r);
+/**
+ * sets the expireation date of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the expireation date to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the inception time of a LDNS_RR_TYPE_RRSIG RR
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the inception time or NULL on failure
+ */
+ldns_rdf* ldns_rr_rrsig_inception(const ldns_rr *r);
+/**
+ * sets the inception date of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the inception date to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the keytag of a LDNS_RR_TYPE_RRSIG RR
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the keytag or NULL on failure
+ */
+ldns_rdf* ldns_rr_rrsig_keytag(const ldns_rr *r);
+/**
+ * sets the keytag of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the keytag to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the signers name of a LDNS_RR_TYPE_RRSIG RR
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the signers name or NULL on failure
+ */
+ldns_rdf* ldns_rr_rrsig_signame(const ldns_rr *r);
+/**
+ * sets the signers name of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the signers name to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the signature data of a LDNS_RR_TYPE_RRSIG RR
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the signature data or NULL on failure
+ */
+ldns_rdf* ldns_rr_rrsig_sig(const ldns_rr *r);
+/**
+ * sets the signature data of a LDNS_RR_TYPE_RRSIG rr
+ * \param[in] r the rr to use
+ * \param[in] f the signature data to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f);
+
+/* DNSKEY */
+/**
+ * returns the flags of a LDNS_RR_TYPE_DNSKEY rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the flags or NULL on failure
+ */
+ldns_rdf* ldns_rr_dnskey_flags(const ldns_rr *r);
+/**
+ * sets the flags of a LDNS_RR_TYPE_DNSKEY rr
+ * \param[in] r the rr to use
+ * \param[in] f the flags to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the protocol of a LDNS_RR_TYPE_DNSKEY rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the protocol or NULL on failure
+ */
+ldns_rdf* ldns_rr_dnskey_protocol(const ldns_rr *r);
+/**
+ * sets the protocol of a LDNS_RR_TYPE_DNSKEY rr
+ * \param[in] r the rr to use
+ * \param[in] f the protocol to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the algorithm of a LDNS_RR_TYPE_DNSKEY rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the algorithm or NULL on failure
+ */
+ldns_rdf* ldns_rr_dnskey_algorithm(const ldns_rr *r);
+/**
+ * sets the algorithm of a LDNS_RR_TYPE_DNSKEY rr
+ * \param[in] r the rr to use
+ * \param[in] f the algorithm to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f);
+/**
+ * returns the key data of a LDNS_RR_TYPE_DNSKEY rr
+ * \param[in] r the resource record
+ * \return a ldns_rdf* with the key data or NULL on failure
+ */
+ldns_rdf* ldns_rr_dnskey_key(const ldns_rr *r);
+/**
+ * sets the key data of a LDNS_RR_TYPE_DNSKEY rr
+ * \param[in] r the rr to use
+ * \param[in] f the key data to set
+ * \return true on success, false otherwise
+ */
+bool ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f);
+
+/**
+ * get the length of the keydata in bits
+ * \param[in] keydata the raw key data
+ * \param[in] len the length of the keydata
+ * \param[in] alg the cryptographic algorithm this is a key for
+ * \return the keysize in bits, or 0 on error
+ */
+size_t ldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
+                                   const size_t len,
+                                   const ldns_algorithm alg);
+
+/**
+ * get the length of the keydata in bits
+ * \param[in] key the key rr to use
+ * \return the keysize in bits
+ */
+size_t ldns_rr_dnskey_key_size(const ldns_rr *key);
+
+/**
+ * The type of function to be passed to ldns_rr_soa_increment_func,
+ * ldns_rr_soa_increment_func_data or ldns_rr_soa_increment_int.
+ * The function will be called with as the first argument the current serial
+ * number of the SOA RR to be updated, and as the second argument a value
+ * given when calling ldns_rr_soa_increment_func_data or 
+ * ldns_rr_soa_increment_int. With ldns_rr_soa_increment_int the pointer
+ * value holds the integer value passed to ldns_rr_soa_increment_int,
+ * and it should be cast to intptr_t to be used as an integer by the
+ * serial modifying function.
+ */
+typedef uint32_t (*ldns_soa_serial_increment_func_t)(uint32_t, void*);
+
+/**
+ * Function to be used with dns_rr_soa_increment_func_int, to set the soa
+ * serial number. 
+ * \param[in] unused the (unused) current serial number.
+ * \param[in] data the serial number to be set.
+ */
+uint32_t ldns_soa_serial_identity(uint32_t unused, void *data);
+
+/**
+ * Function to be used with dns_rr_soa_increment_func, to increment the soa
+ * serial number with one. 
+ * \param[in] s the current serial number.
+ * \param[in] unused unused.
+ */
+uint32_t ldns_soa_serial_increment(uint32_t s, void *unused);
+
+/**
+ * Function to be used with dns_rr_soa_increment_func_int, to increment the soa
+ * serial number with a certain amount. 
+ * \param[in] s the current serial number.
+ * \param[in] data the amount to add to the current serial number.
+ */
+uint32_t ldns_soa_serial_increment_by(uint32_t s, void *data);
+
+/**
+ * Function to be used with ldns_rr_soa_increment_func or 
+ * ldns_rr_soa_increment_func_int to set the soa serial to the number of 
+ * seconds since unix epoch (1-1-1970 00:00). 
+ * When data is given (i.e. the function is called via
+ * ldns_rr_soa_increment_func_int), it is used as the current time. 
+ * When the resulting serial number is smaller than the current serial number,
+ * the current serial number is increased by one.
+ * \param[in] s the current serial number.
+ * \param[in] data the time in seconds since 1-1-1970 00:00
+ */
+uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data);
+
+/**
+ * Function to be used with ldns_rr_soa_increment_func or 
+ * ldns_rr_soa_increment_func_int to set the soa serial to the current date
+ * succeeded by a two digit iteration (datecounter).
+ * When data is given (i.e. the function is called via
+ * ldns_rr_soa_increment_func_int), it is used as the current time. 
+ * When the resulting serial number is smaller than the current serial number,
+ * the current serial number is increased by one.
+ * \param[in] s the current serial number.
+ * \param[in] data the time in seconds since 1-1-1970 00:00
+ */
+uint32_t ldns_soa_serial_datecounter(uint32_t s, void *data);
+
+/**
+ * Increment the serial number of the given SOA by one.
+ * \param[in] soa The soa rr to be incremented
+ */
+void ldns_rr_soa_increment(
+		ldns_rr *soa);
+
+/**
+ * Increment the serial number of the given SOA with the given function.
+ * Included functions to be used here are: ldns_rr_soa_increment, 
+ * ldns_soa_serial_unixtime and ldns_soa_serial_datecounter.
+ * \param[in] soa The soa rr to be incremented
+ * \param[in] f the function to use to increment the soa rr.
+ */
+void ldns_rr_soa_increment_func(
+		ldns_rr *soa, ldns_soa_serial_increment_func_t f);
+
+/**
+ * Increment the serial number of the given SOA with the given function
+ * passing it the given data argument.
+ * \param[in] soa The soa rr to be incremented
+ * \param[in] f the function to use to increment the soa rr.
+ * \param[in] data this argument will be passed to f as the second argument.
+ */
+void ldns_rr_soa_increment_func_data(
+		ldns_rr *soa, ldns_soa_serial_increment_func_t f, void *data);
+
+/**
+ * Increment the serial number of the given SOA with the given function
+ * using data as an argument for the function.
+ * Included functions to be used here are: ldns_soa_serial_identity,
+ * ldns_rr_soa_increment_by, ldns_soa_serial_unixtime and 
+ * ldns_soa_serial_datecounter.
+ * \param[in] soa The soa rr to be incremented
+ * \param[in] f the function to use to increment the soa rr.
+ * \param[in] data this argument will be passed to f as the second argument
+ *                 (by casting it to void*).
+ */
+void ldns_rr_soa_increment_func_int(
+		ldns_rr *soa, ldns_soa_serial_increment_func_t f, int data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_RR_FUNCTIONS_H */
diff --git a/ldns/include/ldns/sha1.h b/ldns/include/ldns/sha1.h
new file mode 100644
index 0000000..d5b1082
--- /dev/null
+++ b/ldns/include/ldns/sha1.h
@@ -0,0 +1,38 @@
+#ifndef LDNS_SHA1_H
+#define LDNS_SHA1_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ 
+#define LDNS_SHA1_BLOCK_LENGTH               64
+#define LDNS_SHA1_DIGEST_LENGTH              20
+
+typedef struct {
+        uint32_t       state[5];
+        uint64_t       count;
+        unsigned char   buffer[LDNS_SHA1_BLOCK_LENGTH];
+} ldns_sha1_ctx;
+  
+void ldns_sha1_init(ldns_sha1_ctx * context);
+void ldns_sha1_transform(uint32_t state[5], const unsigned char buffer[LDNS_SHA1_BLOCK_LENGTH]);
+void ldns_sha1_update(ldns_sha1_ctx *context, const unsigned char *data, unsigned int len);
+void ldns_sha1_final(unsigned char digest[LDNS_SHA1_DIGEST_LENGTH], ldns_sha1_ctx *context);
+
+/**
+ * Convenience function to digest a fixed block of data at once.
+ *
+ * \param[in] data the data to digest
+ * \param[in] data_len the length of data in bytes
+ * \param[out] digest the length of data in bytes
+ *             This pointer MUST have LDNS_SHA1_DIGEST_LENGTH bytes
+ *             available
+ * \return the SHA1 digest of the given data
+ */
+unsigned char *ldns_sha1(unsigned char *data, unsigned int data_len, unsigned char *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_SHA1_H */
diff --git a/ldns/include/ldns/sha2.h b/ldns/include/ldns/sha2.h
new file mode 100644
index 0000000..238767a
--- /dev/null
+++ b/ldns/include/ldns/sha2.h
@@ -0,0 +1,149 @@
+/*
+ * FILE:	sha2.h
+ * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Modified by Jelte Jansen to fit in ldns, and not clash with any
+ * system-defined SHA code.
+ * Changes:
+ *  - Renamed (external) functions and constants to fit ldns style
+ *  - Removed uintXX vs. u_intXX smartness, since ldns needs uintXX
+ *    anyway
+ *  - BYTE ORDER check replaced by simple ifdef as defined or not by
+ *    configure.ac
+ *  - Removed _End and _Data functions
+ *  - Added ldns_shaX(data, len, digest) functions
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
+ */
+
+#ifndef __LDNS_SHA2_H__
+#define __LDNS_SHA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Import u_intXX_t size_t type definitions from system headers.  You
+ * may need to change this, or define these things yourself in this
+ * file.
+ */
+#include <sys/types.h>
+
+#if LDNS_BUILD_CONFIG_HAVE_INTTYPES_H
+
+#include <inttypes.h>
+
+#endif /* LDNS_BUILD_CONFIG_HAVE_INTTYPES_H */
+
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define LDNS_SHA256_BLOCK_LENGTH		64
+#define LDNS_SHA256_DIGEST_LENGTH		32
+#define LDNS_SHA256_DIGEST_STRING_LENGTH	(LDNS_SHA256_DIGEST_LENGTH * 2 + 1)
+#define LDNS_SHA384_BLOCK_LENGTH		128
+#define LDNS_SHA384_DIGEST_LENGTH		48
+#define LDNS_SHA384_DIGEST_STRING_LENGTH	(LDNS_SHA384_DIGEST_LENGTH * 2 + 1)
+#define LDNS_SHA512_BLOCK_LENGTH		128
+#define LDNS_SHA512_DIGEST_LENGTH		64
+#define LDNS_SHA512_DIGEST_STRING_LENGTH	(LDNS_SHA512_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-256/384/512 Context Structures *******************************/
+
+typedef struct _ldns_sha256_CTX {
+	uint32_t	state[8];
+	uint64_t	bitcount;
+	uint8_t	buffer[LDNS_SHA256_BLOCK_LENGTH];
+} ldns_sha256_CTX;
+typedef struct _ldns_sha512_CTX {
+	uint64_t	state[8];
+	uint64_t	bitcount[2];
+	uint8_t	buffer[LDNS_SHA512_BLOCK_LENGTH];
+} ldns_sha512_CTX;
+
+typedef ldns_sha512_CTX ldns_sha384_CTX;
+
+
+/*** SHA-256/384/512 Function Prototypes ******************************/
+void ldns_sha256_init(ldns_sha256_CTX *);
+void ldns_sha256_update(ldns_sha256_CTX*, const uint8_t*, size_t);
+void ldns_sha256_final(uint8_t[LDNS_SHA256_DIGEST_LENGTH], ldns_sha256_CTX*);
+
+void ldns_sha384_init(ldns_sha384_CTX*);
+void ldns_sha384_update(ldns_sha384_CTX*, const uint8_t*, size_t);
+void ldns_sha384_final(uint8_t[LDNS_SHA384_DIGEST_LENGTH], ldns_sha384_CTX*);
+
+void ldns_sha512_init(ldns_sha512_CTX*);
+void ldns_sha512_update(ldns_sha512_CTX*, const uint8_t*, size_t);
+void ldns_sha512_final(uint8_t[LDNS_SHA512_DIGEST_LENGTH], ldns_sha512_CTX*);
+
+/**
+ * Convenience function to digest a fixed block of data at once.
+ *
+ * \param[in] data the data to digest
+ * \param[in] data_len the length of data in bytes
+ * \param[out] digest the length of data in bytes
+ *             This pointer MUST have LDNS_SHA256_DIGEST_LENGTH bytes
+ *             available
+ * \return the SHA1 digest of the given data
+ */
+unsigned char *ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest);
+
+/**
+ * Convenience function to digest a fixed block of data at once.
+ *
+ * \param[in] data the data to digest
+ * \param[in] data_len the length of data in bytes
+ * \param[out] digest the length of data in bytes
+ *             This pointer MUST have LDNS_SHA384_DIGEST_LENGTH bytes
+ *             available
+ * \return the SHA1 digest of the given data
+ */
+unsigned char *ldns_sha384(unsigned char *data, unsigned int data_len, unsigned char *digest);
+
+/**
+ * Convenience function to digest a fixed block of data at once.
+ *
+ * \param[in] data the data to digest
+ * \param[in] data_len the length of data in bytes
+ * \param[out] digest the length of data in bytes
+ *             This pointer MUST have LDNS_SHA512_DIGEST_LENGTH bytes
+ *             available
+ * \return the SHA1 digest of the given data
+ */
+unsigned char *ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest);
+
+#ifdef	__cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LDNS_SHA2_H__ */
diff --git a/ldns/include/ldns/str2host.h b/ldns/include/ldns/str2host.h
new file mode 100644
index 0000000..d639970
--- /dev/null
+++ b/ldns/include/ldns/str2host.h
@@ -0,0 +1,319 @@
+/**
+ * str2host.h - conversion from str to the host fmt
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#ifndef LDNS_2HOST_H
+#define LDNS_2HOST_H
+
+#include <ldns/common.h>
+#include <ldns/error.h>
+#include <ldns/rr.h>
+#include <ldns/rdata.h>
+#include <ldns/packet.h>
+#include <ldns/buffer.h>
+#include <ctype.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \file
+ *
+ * Defines functions to convert dns data in presentation format or text files
+ * to internal structures.
+ */
+
+/**
+ * convert a byte into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] bytestr the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr);
+
+/**
+ * convert a string to a int16 in wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] shortstr the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr);
+
+/**
+ * convert a strings into a 4 byte int in wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] longstr the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr);
+
+/**
+ * convert a time string to a time value in wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] time the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_time(ldns_rdf **rd, const char *time);
+
+/* convert string with NSEC3 salt to wireformat) 
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * return ldns_status
+ */
+ldns_status ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *nsec3_salt);
+
+/* convert a time period (think TTL's) to wireformat) 
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * return ldns_status
+ */
+ldns_status ldns_str2rdf_period(ldns_rdf **rd, const char *str);
+
+/**
+ * convert str with an A record into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_a(ldns_rdf **rd, const char *str);
+
+/**
+ * convert the str with an AAAA record into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a string into wireformat (think txt record)
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted (NULL terminated)
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_str(ldns_rdf **rd, const char *str);
+
+/**
+ * convert str with the apl record into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_apl(ldns_rdf **rd, const char *str);
+
+/**
+ * convert the string with the b64 data into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_b64(ldns_rdf **rd, const char *str);
+
+/**
+ * convert the string with the b32 ext hex data into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a hex value into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_hex(ldns_rdf **rd, const char *str);
+
+/**
+ * convert string with nsec into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_nsec(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a rrtype into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_type(ldns_rdf **rd, const char *str);
+
+/**
+ * convert string with a classname into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_class(ldns_rdf **rd, const char *str);
+
+/**
+ * convert an certificate algorithm value into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str);
+
+/**
+ * convert an algorithm value into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_alg(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a tlsa certificate usage value into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_certificate_usage(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a tlsa selector value into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_selector(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a tlsa matching type value into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_matching_type(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a string with a unknown RR into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_unknown(ldns_rdf **rd, const char *str);
+
+/**
+ * convert string with a protocol service into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_service(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a string with a LOC RR into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_loc(ldns_rdf **rd, const char *str);
+
+/**
+ * convert string with a WKS RR into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_wks(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a str with a NSAP RR into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_nsap(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a str with a ATMA RR into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_atma(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a str with a IPSECKEY RR into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str);
+
+/**
+ * convert a dname string into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_dname(ldns_rdf **rd, const char *str);
+
+/**
+ * convert 4 * 16bit hex separated by colons into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_ilnp64(ldns_rdf **rd, const char *str);
+
+/**
+ * convert 6 hex bytes separated by dashes into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_eui48(ldns_rdf **rd, const char *str);
+
+/**
+ * convert 8 hex bytes separated by dashes into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_eui64(ldns_rdf **rd, const char *str);
+
+/**
+ * Convert a non-zero sequence of US-ASCII letters and numbers into wireformat
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_tag(ldns_rdf **rd, const char *str);
+
+/**
+ * Convert a <character-string> encoding of the value field as specified 
+ * [RFC1035], Section 5.1., encoded as one bug chunk of data.
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_long_str(ldns_rdf **rd, const char *str);
+
+/**
+ * Convert a "<algorithm> <hit> <pk>" encoding of the value field as specified 
+ * in Section 6. of [RFC5205], encoded as wireformat as specified in Section 5.
+ * of [RFC5205].
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_hip(ldns_rdf **rd, const char *str);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_2HOST_H */
diff --git a/ldns/include/ldns/tsig.h b/ldns/include/ldns/tsig.h
new file mode 100644
index 0000000..676045f
--- /dev/null
+++ b/ldns/include/ldns/tsig.h
@@ -0,0 +1,101 @@
+/*
+ * tsig.h -- defines for TSIG [RFC2845]
+ *
+ * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ */
+
+#ifndef LDNS_TSIG_H
+#define LDNS_TSIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \file
+ *
+ * Defines functions for TSIG usage
+ */
+
+
+/**
+ * Contains credentials for TSIG
+*/
+typedef struct ldns_tsig_credentials_struct
+{
+    char *algorithm;
+    char *keyname;
+    char *keydata;
+    /* XXX More eventually. */
+} ldns_tsig_credentials;
+
+char *ldns_tsig_algorithm(ldns_tsig_credentials *);
+char *ldns_tsig_keyname(ldns_tsig_credentials *);
+char *ldns_tsig_keydata(ldns_tsig_credentials *);
+char *ldns_tsig_keyname_clone(ldns_tsig_credentials *);
+char *ldns_tsig_keydata_clone(ldns_tsig_credentials *);
+
+/**
+ * verifies the tsig rr for the given packet and key.
+ * The wire must be given too because tsig does not sign normalized packets.
+ * \param[in] pkt the packet to verify
+ * \param[in] wire needed to verify the mac
+ * \param[in] wire_size size of wire
+ * \param[in] key_name the name of the shared key
+ * \param[in] key_data the key in base 64 format
+ * \param[in] mac original mac
+ * \return true if tsig is correct, false if not, or if tsig is not set
+ */
+bool ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, ldns_rdf *mac);
+
+/**
+ * verifies the tsig rr for the given packet and key.
+ * The wire must be given too because tsig does not sign normalized packets.
+ * \param[in] pkt the packet to verify
+ * \param[in] wire needed to verify the mac
+ * \param[in] wire_size size of wire
+ * \param[in] key_name the name of the shared key
+ * \param[in] key_data the key in base 64 format
+ * \param[in] mac original mac
+ * \param[in] tsig_timers_only must be zero for the first packet and positive for subsequent packets. If zero, all digest
+   components are used to verify the _mac. If non-zero, only the TSIG timers are used to verify the mac.
+ * \return true if tsig is correct, false if not, or if tsig is not set
+ */
+bool ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wire_size, const char *key_name, const char *key_data, ldns_rdf *mac,
+    int tsig_timers_only);
+
+/**
+ * creates a tsig rr for the given packet and key.
+ * \param[in] pkt the packet to sign
+ * \param[in] key_name the name of the shared key
+ * \param[in] key_data the key in base 64 format
+ * \param[in] fudge seconds of error permitted in time signed
+ * \param[in] algorithm_name the name of the algorithm used
+ * \param[in] query_mac is added to the digest if not NULL (so NULL is for signing queries, not NULL is for signing answers)
+ * \return status (OK if success)
+ */
+ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge,
+    const char *algorithm_name, ldns_rdf *query_mac);
+
+/**
+ * creates a tsig rr for the given packet and key.
+ * \param[in] pkt the packet to sign
+ * \param[in] key_name the name of the shared key
+ * \param[in] key_data the key in base 64 format
+ * \param[in] fudge seconds of error permitted in time signed
+ * \param[in] algorithm_name the name of the algorithm used
+ * \param[in] query_mac is added to the digest if not NULL (so NULL is for signing queries, not NULL is for signing answers)
+ * \param[in] tsig_timers_only must be zero for the first packet and positive for subsequent packets. If zero, all digest
+   components are used to create the query_mac. If non-zero, only the TSIG timers are used to create the query_mac.
+ * \return status (OK if success)
+ */
+ldns_status ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge,
+    const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_TSIG_H */
diff --git a/ldns/include/ldns/update.h b/ldns/include/ldns/update.h
new file mode 100644
index 0000000..d3459d3
--- /dev/null
+++ b/ldns/include/ldns/update.h
@@ -0,0 +1,115 @@
+/*
+ * update.h
+ *
+ * Functions for RFC 2136 Dynamic Update
+ *
+ * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ */
+
+/**
+ * \file
+ *
+ * Defines functions to perform UPDATE queries
+ */
+
+
+#ifndef LDNS_UPDATE_H
+#define LDNS_UPDATE_H
+
+#include <ldns/resolver.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * create an update packet from zone name, class and the rr lists
+ * \param[in] zone_rdf name of the zone
+ * \param[in] clas zone class
+ * \param[in] pr_rrlist list of Prerequisite Section RRs
+ * \param[in] up_rrlist list of Updates Section RRs
+ * \param[in] ad_rrlist list of Additional Data Section RRs (currently unused)
+ * \return the new packet
+ */
+ldns_pkt *ldns_update_pkt_new(ldns_rdf *zone_rdf, ldns_rr_class clas, ldns_rr_list *pr_rrlist, ldns_rr_list *up_rrlist, ldns_rr_list *ad_rrlist);
+
+/**
+ * add tsig credentials to
+ * a packet from a resolver
+ * \param[in] p packet to copy to
+ * \param[in] r resolver to copy from
+ *
+ * \return status wether successfull or not
+ */
+ldns_status ldns_update_pkt_tsig_add(ldns_pkt *p, ldns_resolver *r);
+
+/* access functions */
+
+/**
+ * Get the zo count
+ * \param[in] p the packet
+ * \return the zo count
+ */
+uint16_t ldns_update_zocount(const ldns_pkt *p);
+/**
+ * Get the zo count
+ * \param[in] p the packet
+ * \return the pr count
+ */
+uint16_t ldns_update_prcount(const ldns_pkt *p);
+/**
+ * Get the zo count
+ * \param[in] p the packet
+ * \return the up count
+ */
+uint16_t ldns_update_upcount(const ldns_pkt *p);
+/**
+ * Get the zo count
+ * \param[in] p the packet
+ * \return the ad count
+ */
+uint16_t ldns_update_ad(const ldns_pkt *p);
+/**
+ * Set the zo count
+ * \param[in] p the packet
+ * \param[in] c the zo count to set
+ */
+void ldns_update_set_zo(ldns_pkt *p, uint16_t c);
+/**
+ * Set the pr count
+ * \param[in] p the packet
+ * \param[in] c the pr count to set
+ */
+void ldns_update_set_prcount(ldns_pkt *p, uint16_t c);
+/**
+ * Set the up count
+ * \param[in] p the packet
+ * \param[in] c the up count to set
+ */
+void ldns_update_set_upcount(ldns_pkt *p, uint16_t c);
+/**
+ * Set the ad count
+ * \param[in] p the packet
+ * \param[in] c the ad count to set
+ */
+void ldns_update_set_adcount(ldns_pkt *p, uint16_t c);
+
+/* soa functions that need to be configured */
+/*
+ * Not sure if we want to keep these like this, therefore
+ * not documented
+ */
+ldns_status ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r, ldns_rr_class c, ldns_rdf **mname);
+/* 
+ * Not sure if we want to keep these like this, therefore
+ * not documented
+ */
+ldns_status ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, ldns_rr_class c, ldns_rdf **zone_rdf, ldns_rdf **mname_rdf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* LDNS_UPDATE_H */
diff --git a/ldns/include/ldns/util.h b/ldns/include/ldns/util.h
new file mode 100644
index 0000000..86848eb
--- /dev/null
+++ b/ldns/include/ldns/util.h
@@ -0,0 +1,392 @@
+/*
+ * util.h
+ *  
+ * helper function header file
+ * 
+ * a Net::DNS like library for C
+ * 
+ * (c) NLnet Labs, 2004
+ * 
+ * See the file LICENSE for the license
+ */
+
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#include "EXTERN.h"
+#include "perl.h"
+#include <ldns/common.h>
+#include <time.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define dprintf(X,Y) fprintf(stderr, (X), (Y))
+/* #define	dprintf(X, Y)  */
+
+#define LDNS_VERSION "1.6.18"
+#define LDNS_REVISION ((1<<16)|(6<<8)|(18))
+
+/**
+ * splint static inline workaround
+ */
+#ifdef S_SPLINT_S
+#  define INLINE 
+#else
+#  ifdef SWIG
+#    define INLINE static
+#  else
+#    define INLINE static inline
+#  endif
+#endif
+
+/**
+ * Memory management macros
+ */
+#define LDNS_MALLOC(type)		LDNS_XMALLOC(type, 1)
+
+#define LDNS_XMALLOC(type, count)	((type *) malloc((count) * sizeof(type)))
+
+#define LDNS_CALLOC(type, count)	((type *) calloc((count), sizeof(type)))
+
+#define LDNS_REALLOC(ptr, type)		LDNS_XREALLOC((ptr), type, 1)
+
+#define LDNS_XREALLOC(ptr, type, count)				\
+	((type *) realloc((ptr), (count) * sizeof(type)))
+
+#define LDNS_FREE(ptr) \
+	do { free((ptr)); (ptr) = NULL; } while (0)
+
+#define LDNS_DEP     printf("DEPRECATED FUNCTION!\n");
+
+/*
+ * Copy data allowing for unaligned accesses in network byte order
+ * (big endian).
+ */
+INLINE uint16_t
+ldns_read_uint16(const void *src)
+{
+#ifdef ALLOW_UNALIGNED_ACCESSES
+	return ntohs(*(const uint16_t *) src);
+#else
+	const uint8_t *p = (const uint8_t *) src;
+	return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
+#endif
+}
+
+INLINE uint32_t
+ldns_read_uint32(const void *src)
+{
+#ifdef ALLOW_UNALIGNED_ACCESSES
+	return ntohl(*(const uint32_t *) src);
+#else
+	const uint8_t *p = (const uint8_t *) src;
+	return (  ((uint32_t) p[0] << 24)
+		| ((uint32_t) p[1] << 16)
+		| ((uint32_t) p[2] << 8)
+		|  (uint32_t) p[3]);
+#endif
+}
+
+/*
+ * Copy data allowing for unaligned accesses in network byte order
+ * (big endian).
+ */
+INLINE void
+ldns_write_uint16(void *dst, uint16_t data)
+{
+#ifdef ALLOW_UNALIGNED_ACCESSES
+	* (uint16_t *) dst = htons(data);
+#else
+	uint8_t *p = (uint8_t *) dst;
+	p[0] = (uint8_t) ((data >> 8) & 0xff);
+	p[1] = (uint8_t) (data & 0xff);
+#endif
+}
+
+INLINE void
+ldns_write_uint32(void *dst, uint32_t data)
+{
+#ifdef ALLOW_UNALIGNED_ACCESSES
+	* (uint32_t *) dst = htonl(data);
+#else
+	uint8_t *p = (uint8_t *) dst;
+	p[0] = (uint8_t) ((data >> 24) & 0xff);
+	p[1] = (uint8_t) ((data >> 16) & 0xff);
+	p[2] = (uint8_t) ((data >> 8) & 0xff);
+	p[3] = (uint8_t) (data & 0xff);
+#endif
+}
+
+/* warning. */
+INLINE void
+ldns_write_uint64_as_uint48(void *dst, uint64_t data)
+{
+	uint8_t *p = (uint8_t *) dst;
+	p[0] = (uint8_t) ((data >> 40) & 0xff);
+	p[1] = (uint8_t) ((data >> 32) & 0xff);
+	p[2] = (uint8_t) ((data >> 24) & 0xff);
+	p[3] = (uint8_t) ((data >> 16) & 0xff);
+	p[4] = (uint8_t) ((data >> 8) & 0xff);
+	p[5] = (uint8_t) (data & 0xff);
+}
+
+
+/**
+ * Structure to do a Schwartzian-like transformation, for instance when
+ * sorting. If you need a transformation on the objects that are sorted,
+ * you can sue this to store the transformed values, so you do not
+ * need to do the transformation again for each comparison
+ */
+struct ldns_schwartzian_compare_struct {
+	void *original_object;
+	void *transformed_object;
+};
+
+/** A general purpose lookup table
+ *  
+ *  Lookup tables are arrays of (id, name) pairs,
+ *  So you can for instance lookup the RCODE 3, which is "NXDOMAIN",
+ *  and vice versa. The lookup tables themselves are defined wherever needed,
+ *  for instance in \ref host2str.c
+ */
+struct ldns_struct_lookup_table {
+        int id;
+        const char *name;
+};
+typedef struct ldns_struct_lookup_table ldns_lookup_table;
+  
+/**
+ * Looks up the table entry by name, returns NULL if not found.
+ * \param[in] table the lookup table to search in
+ * \param[in] name what to search for
+ * \return the item found
+ */
+ldns_lookup_table *ldns_lookup_by_name(ldns_lookup_table table[],
+                                       const char *name);
+
+/**
+ * Looks up the table entry by id, returns NULL if not found.
+ * \param[in] table the lookup table to search in
+ * \param[in] id what to search for
+ * \return the item found
+ */
+ldns_lookup_table *ldns_lookup_by_id(ldns_lookup_table table[], int id);
+
+/**
+ * Returns the value of the specified bit
+ * The bits are counted from left to right, so bit #0 is the
+ * left most bit.
+ * \param[in] bits array holding the bits
+ * \param[in] index to the wanted bit
+ * \return 
+ */
+int ldns_get_bit(uint8_t bits[], size_t index);
+
+
+/**
+ * Returns the value of the specified bit
+ * The bits are counted from right to left, so bit #0 is the
+ * right most bit.
+ * \param[in] bits array holding the bits
+ * \param[in] index to the wanted bit
+ * \return 1 or 0 depending no the bit state
+ */
+int ldns_get_bit_r(uint8_t bits[], size_t index);
+
+/**
+ * sets the specified bit in the specified byte to
+ * 1 if value is true, 0 if false
+ * The bits are counted from right to left, so bit #0 is the
+ * right most bit.
+ * \param[in] byte the bit to set the bit in
+ * \param[in] bit_nr the bit to set (0 <= n <= 7)
+ * \param[in] value whether to set the bit to 1 or 0
+ * \return 1 or 0 depending no the bit state
+ */
+void ldns_set_bit(uint8_t *byte, int bit_nr, bool value);
+
+/**
+ * Returns the value of a to the power of b
+ * (or 1 of b < 1)
+ */
+/*@unused@*/
+INLINE long
+ldns_power(long a, long b) {
+	long result = 1;
+	while (b > 0) {
+		if (b & 1) {
+			result *= a;
+			if (b == 1) {
+				return result;
+			}
+		}
+		a *= a;
+		b /= 2;
+	}
+	return result;
+}
+
+/**
+ * Returns the int value of the given (hex) digit
+ * \param[in] ch the hex char to convert
+ * \return the converted decimal value
+ */
+int ldns_hexdigit_to_int(char ch);
+
+/**
+ * Returns the char (hex) representation of the given int
+ * \param[in] ch the int to convert
+ * \return the converted hex char
+ */
+char ldns_int_to_hexdigit(int ch);
+
+/**
+ * Converts a hex string to binary data
+ *
+ * \param[out] data The binary result is placed here.
+ * At least strlen(str)/2 bytes should be allocated
+ * \param[in] str The hex string to convert.
+ * This string should not contain spaces
+ * \return The number of bytes of converted data, or -1 if one of the arguments * is NULL, or -2 if the string length is not an even number
+ */
+int
+ldns_hexstring_to_data(uint8_t *data, const char *str);
+
+/**
+ * Show the internal library version
+ * \return a string with the version in it
+ */
+const char * ldns_version(void);
+
+/**
+ * Convert TM to seconds since epoch (midnight, January 1st, 1970).
+ * Like timegm(3), which is not always available.
+ * \param[in] tm a struct tm* with the date
+ * \return the seconds since epoch
+ */
+time_t ldns_mktime_from_utc(const struct tm *tm);
+
+time_t mktime_from_utc(const struct tm *tm);
+
+/**
+ * The function interprets time as the number of seconds since epoch
+ * with respect to now using serial arithmitics (rfc1982).
+ * That number of seconds is then converted to broken-out time information.
+ * This is especially usefull when converting the inception and expiration
+ * fields of RRSIG records.
+ *
+ * \param[in] time number of seconds since epoch (midnight, January 1st, 1970)
+ *            to be intepreted as a serial arithmitics number relative to now.
+ * \param[in] now number of seconds since epoch (midnight, January 1st, 1970)
+ *            to which the time value is compared to determine the final value.
+ * \param[out] result the struct with the broken-out time information
+ * \return result on success or NULL on error
+ */
+struct tm * ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result);
+ 
+/**
+ * Seed the random function.
+ * If the file descriptor is specified, the random generator is seeded with
+ * data from that file. If not, /dev/urandom is used.
+ *
+ * applications should call this if they need entropy data within ldns
+ * If openSSL is available, it is automatically seeded from /dev/urandom
+ * or /dev/random.
+ *
+ * If you need more entropy, or have no openssl available, this function
+ * MUST be called at the start of the program
+ *
+ * If openssl *is* available, this function just adds more entropy
+ *
+ * \param[in] fd a file providing entropy data for the seed
+ * \param[in] size the number of bytes to use as entropy data. If this is 0,
+ *            only the minimal amount is taken (usually 4 bytes)
+ * \return 0 if seeding succeeds, 1 if it fails
+ */
+int ldns_init_random(FILE *fd, unsigned int size);
+
+/**
+ * Get random number.
+ * \return random number.
+ *
+ */
+uint16_t ldns_get_random(void);
+
+/**
+ * Encode data as BubbleBabble
+ *
+ * \param[in] data a pointer to data to be encoded
+ * \param[in] len size the number of bytes of data
+ * \return a string of BubbleBabble
+ */
+char *ldns_bubblebabble(uint8_t *data, size_t len);
+
+
+INLINE time_t ldns_time(time_t *t) { return time(t); }
+
+
+/**
+ * calculates the size needed to store the result of b32_ntop
+ */
+/*@unused@*/
+INLINE size_t ldns_b32_ntop_calculate_size(size_t src_data_length)
+{
+	return src_data_length == 0 ? 0 : ((src_data_length - 1) / 5 + 1) * 8;
+}
+
+INLINE size_t ldns_b32_ntop_calculate_size_no_padding(size_t src_data_length)
+{
+	return ((src_data_length + 3) * 8 / 5) - 4;
+}
+
+int ldns_b32_ntop(const uint8_t* src_data, size_t src_data_length,
+	     char* target_text_buffer, size_t target_text_buffer_size);
+
+int ldns_b32_ntop_extended_hex(const uint8_t* src_data, size_t src_data_length,
+	     char* target_text_buffer, size_t target_text_buffer_size);
+
+#if ! LDNS_BUILD_CONFIG_HAVE_B32_NTOP
+
+int b32_ntop(const uint8_t* src_data, size_t src_data_length,
+	     char* target_text_buffer, size_t target_text_buffer_size);
+
+int b32_ntop_extended_hex(const uint8_t* src_data, size_t src_data_length,
+	     char* target_text_buffer, size_t target_text_buffer_size);
+
+#endif /* ! LDNS_BUILD_CONFIG_HAVE_B32_NTOP */
+
+
+/**
+ * calculates the size needed to store the result of b32_pton
+ */
+/*@unused@*/
+INLINE size_t ldns_b32_pton_calculate_size(size_t src_text_length)
+{
+	return src_text_length * 5 / 8;
+}
+
+int ldns_b32_pton(const char* src_text, size_t src_text_length,
+	       	uint8_t* target_data_buffer, size_t target_data_buffer_size);
+
+int ldns_b32_pton_extended_hex(const char* src_text, size_t src_text_length,
+		uint8_t* target_data_buffer, size_t target_data_buffer_size);
+
+#if ! LDNS_BUILD_CONFIG_HAVE_B32_PTON
+
+int b32_pton(const char* src_text, size_t src_text_length,
+	       	uint8_t* target_data_buffer, size_t target_data_buffer_size);
+
+int b32_pton_extended_hex(const char* src_text, size_t src_text_length,
+		uint8_t* target_data_buffer, size_t target_data_buffer_size);
+
+#endif /* ! LDNS_BUILD_CONFIG_HAVE_B32_PTON */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_UTIL_H */
diff --git a/ldns/include/ldns/wire2host.h b/ldns/include/ldns/wire2host.h
new file mode 100644
index 0000000..53155b3
--- /dev/null
+++ b/ldns/include/ldns/wire2host.h
@@ -0,0 +1,197 @@
+/*
+ * wire2host.h - from wire conversion routines
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file
+ *
+ * Contains functions that translate dns data from the wire format (as sent
+ * by servers and clients) to the internal structures.
+ */
+ 
+#ifndef LDNS_WIRE2HOST_H
+#define LDNS_WIRE2HOST_H
+
+#include <ldns/rdata.h>
+#include <ldns/common.h>
+#include <ldns/error.h>
+#include <ldns/rr.h>
+#include <ldns/packet.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The length of the header */
+#define	LDNS_HEADER_SIZE	12
+
+/* First octet of flags */
+#define	LDNS_RD_MASK		0x01U
+#define	LDNS_RD_SHIFT	0
+#define	LDNS_RD_WIRE(wirebuf)	(*(wirebuf+2) & LDNS_RD_MASK)
+#define	LDNS_RD_SET(wirebuf)	(*(wirebuf+2) |= LDNS_RD_MASK)
+#define	LDNS_RD_CLR(wirebuf)	(*(wirebuf+2) &= ~LDNS_RD_MASK)
+
+#define LDNS_TC_MASK		0x02U
+#define LDNS_TC_SHIFT	1
+#define	LDNS_TC_WIRE(wirebuf)	(*(wirebuf+2) & LDNS_TC_MASK)
+#define	LDNS_TC_SET(wirebuf)	(*(wirebuf+2) |= LDNS_TC_MASK)
+#define	LDNS_TC_CLR(wirebuf)	(*(wirebuf+2) &= ~LDNS_TC_MASK)
+
+#define	LDNS_AA_MASK		0x04U
+#define	LDNS_AA_SHIFT	2
+#define	LDNS_AA_WIRE(wirebuf)	(*(wirebuf+2) & LDNS_AA_MASK)
+#define	LDNS_AA_SET(wirebuf)	(*(wirebuf+2) |= LDNS_AA_MASK)
+#define	LDNS_AA_CLR(wirebuf)	(*(wirebuf+2) &= ~LDNS_AA_MASK)
+
+#define	LDNS_OPCODE_MASK	0x78U
+#define	LDNS_OPCODE_SHIFT	3
+#define	LDNS_OPCODE_WIRE(wirebuf)	((*(wirebuf+2) & LDNS_OPCODE_MASK) >> LDNS_OPCODE_SHIFT)
+#define	LDNS_OPCODE_SET(wirebuf, opcode) \
+	(*(wirebuf+2) = ((*(wirebuf+2)) & ~LDNS_OPCODE_MASK) | ((opcode) << LDNS_OPCODE_SHIFT))
+
+#define	LDNS_QR_MASK		0x80U
+#define	LDNS_QR_SHIFT	7
+#define	LDNS_QR_WIRE(wirebuf)	(*(wirebuf+2) & LDNS_QR_MASK)
+#define	LDNS_QR_SET(wirebuf)	(*(wirebuf+2) |= LDNS_QR_MASK)
+#define	LDNS_QR_CLR(wirebuf)	(*(wirebuf+2) &= ~LDNS_QR_MASK)
+
+/* Second octet of flags */
+#define	LDNS_RCODE_MASK	0x0fU
+#define	LDNS_RCODE_SHIFT	0
+#define	LDNS_RCODE_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_RCODE_MASK)
+#define	LDNS_RCODE_SET(wirebuf, rcode) \
+	(*(wirebuf+3) = ((*(wirebuf+3)) & ~LDNS_RCODE_MASK) | (rcode))
+
+#define	LDNS_CD_MASK		0x10U
+#define	LDNS_CD_SHIFT	4
+#define	LDNS_CD_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_CD_MASK)
+#define	LDNS_CD_SET(wirebuf)	(*(wirebuf+3) |= LDNS_CD_MASK)
+#define	LDNS_CD_CLR(wirebuf)	(*(wirebuf+3) &= ~LDNS_CD_MASK)
+
+#define	LDNS_AD_MASK		0x20U
+#define	LDNS_AD_SHIFT	5
+#define	LDNS_AD_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_AD_MASK)
+#define	LDNS_AD_SET(wirebuf)	(*(wirebuf+3) |= LDNS_AD_MASK)
+#define	LDNS_AD_CLR(wirebuf)	(*(wirebuf+3) &= ~LDNS_AD_MASK)
+
+#define	LDNS_Z_MASK		0x40U
+#define	LDNS_Z_SHIFT		6
+#define	LDNS_Z_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_Z_MASK)
+#define	LDNS_Z_SET(wirebuf)	(*(wirebuf+3) |= LDNS_Z_MASK)
+#define	LDNS_Z_CLR(wirebuf)	(*(wirebuf+3) &= ~LDNS_Z_MASK)
+
+#define	LDNS_RA_MASK		0x80U
+#define	LDNS_RA_SHIFT	7
+#define	LDNS_RA_WIRE(wirebuf)	(*(wirebuf+3) & LDNS_RA_MASK)
+#define	LDNS_RA_SET(wirebuf)	(*(wirebuf+3) |= LDNS_RA_MASK)
+#define	LDNS_RA_CLR(wirebuf)	(*(wirebuf+3) &= ~LDNS_RA_MASK)
+
+/* Query ID */
+#define	LDNS_ID_WIRE(wirebuf)		(ldns_read_uint16(wirebuf))
+#define	LDNS_ID_SET(wirebuf, id)	(ldns_write_uint16(wirebuf, id))
+
+/* Counter of the question section */
+#define LDNS_QDCOUNT_OFF		4
+/*
+#define	QDCOUNT(wirebuf)		(ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
+*/
+#define	LDNS_QDCOUNT(wirebuf)		(ldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF))
+
+/* Counter of the answer section */
+#define LDNS_ANCOUNT_OFF		6
+#define	LDNS_ANCOUNT(wirebuf)		(ldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF))
+
+/* Counter of the authority section */
+#define LDNS_NSCOUNT_OFF		8
+#define	LDNS_NSCOUNT(wirebuf)		(ldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF))
+
+/* Counter of the additional section */
+#define LDNS_ARCOUNT_OFF		10
+#define	LDNS_ARCOUNT(wirebuf)		(ldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF))
+
+/**
+ * converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
+ * This function will initialize and allocate memory space for the packet 
+ * structure.
+ * 
+ * \param[in] packet pointer to the structure to hold the packet
+ * \param[in] data pointer to the buffer with the data
+ * \param[in] len the length of the data buffer (in bytes)
+ * \return LDNS_STATUS_OK if everything succeeds, error otherwise
+ */
+ldns_status ldns_wire2pkt(ldns_pkt **packet, const uint8_t *data, size_t len);
+
+/**
+ * converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
+ * This function will initialize and allocate memory space for the packet 
+ * structure.
+ * 
+ * \param[in] packet pointer to the structure to hold the packet
+ * \param[in] buffer the buffer with the data
+ * \return LDNS_STATUS_OK if everything succeeds, error otherwise
+ */
+ldns_status ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer);
+
+/**
+ * converts the data on the uint8_t bytearray (in wire format) to a DNS 
+ * dname rdata field. This function will initialize and allocate memory
+ * space for the dname structure. The length of the wiredata of this rdf 
+ * is added to the *pos value.
+ *
+ * \param[in] dname pointer to the structure to hold the rdata value
+ * \param[in] wire pointer to the buffer with the data
+ * \param[in] max the length of the data buffer (in bytes)
+ * \param[in] pos the position of the rdf in the buffer (ie. the number of bytes 
+ *            from the start of the buffer)
+ * \return LDNS_STATUS_OK if everything succeeds, error otherwise
+ */
+ldns_status ldns_wire2dname(ldns_rdf **dname, const uint8_t *wire, size_t max, size_t *pos);
+
+/**
+ * converts the data on the uint8_t bytearray (in wire format) to DNS 
+ * rdata fields, and adds them to the list of rdfs of the given rr.
+ * This function will initialize and allocate memory space for the dname
+ * structures.
+ * The length of the wiredata of these rdfs is added to the *pos value.
+ *
+ * All rdfs belonging to the RR are read; the rr should have no rdfs
+ * yet. An error is returned if the format cannot be parsed.
+ *
+ * \param[in] rr pointer to the ldns_rr structure to hold the rdata value
+ * \param[in] wire pointer to the buffer with the data
+ * \param[in] max the length of the data buffer (in bytes)
+ * \param[in] pos the position of the rdf in the buffer (ie. the number of bytes 
+ *            from the start of the buffer)
+ * \return LDNS_STATUS_OK if everything succeeds, error otherwise
+ */
+ldns_status ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos);
+
+/**
+ * converts the data on the uint8_t bytearray (in wire format) to a DNS 
+ * resource record.
+ * This function will initialize and allocate memory space for the rr
+ * structure.
+ * The length of the wiredata of this rr is added to the *pos value.
+ * 
+ * \param[in] rr pointer to the structure to hold the rdata value
+ * \param[in] wire pointer to the buffer with the data
+ * \param[in] max the length of the data buffer (in bytes)
+ * \param[in] pos the position of the rr in the buffer (ie. the number of bytes 
+ *            from the start of the buffer)
+ * \param[in] section the section in the packet the rr is meant for
+ * \return LDNS_STATUS_OK if everything succeeds, error otherwise
+ */
+ldns_status ldns_wire2rr(ldns_rr **rr, const uint8_t *wire, size_t max, size_t *pos, ldns_pkt_section section);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_WIRE2HOST_H */
diff --git a/ldns/include/ldns/zone.h b/ldns/include/ldns/zone.h
new file mode 100644
index 0000000..0d129a0
--- /dev/null
+++ b/ldns/include/ldns/zone.h
@@ -0,0 +1,176 @@
+/**
+ * zone.h
+ *
+ * zone definitions
+ *  - what is it
+ *  - get_glue function
+ *  - search etc
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+/**
+ * \file
+ *
+ * Defines the ldns_zone structure and functions to manipulate it.
+ */
+ 
+
+#ifndef LDNS_ZONE_H
+#define LDNS_ZONE_H
+
+#include <ldns/common.h>
+#include <ldns/rdata.h>
+#include <ldns/rr.h>
+#include <ldns/error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** 
+ * DNS Zone
+ *
+ * A list of RR's with some
+ * extra information which comes from the SOA RR
+ * Note: nothing has been done to make this efficient (yet).
+ */
+struct ldns_struct_zone
+{
+	/** the soa defines a zone */
+	ldns_rr 	*_soa;
+	/* basicly a zone is a list of rr's */
+	ldns_rr_list 	*_rrs;
+	/* we could change this to be a b-tree etc etc todo */
+};
+typedef struct ldns_struct_zone ldns_zone;	
+	
+/**
+ * create a new ldns_zone structure
+ * \return a pointer to a ldns_zone structure
+ */
+ldns_zone * ldns_zone_new(void);
+
+/**
+ * Return the soa record of a zone
+ * \param[in] z the zone to read from
+ * \return the soa record in the zone
+ */
+ldns_rr * ldns_zone_soa(const ldns_zone *z);
+
+/**
+ * Returns the number of resource records in the zone, NOT counting the SOA record
+ * \param[in] z the zone to read from
+ * \return the number of rr's in the zone
+ */
+size_t ldns_zone_rr_count(const ldns_zone *z);
+
+/**
+ * Set the zone's soa record
+ * \param[in] z the zone to put the new soa in
+ * \param[in] soa the soa to set
+ */
+void ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa);
+
+/**
+ * Get a list of a zone's content. Note that the SOA
+ * isn't included in this list. You need to get the 
+ * with ldns_zone_soa.
+ * \param[in] z the zone to read from
+ * \return the rrs from this zone
+ */
+ldns_rr_list * ldns_zone_rrs(const ldns_zone *z);
+
+/**
+ * Set the zone's contents
+ * \param[in] z the zone to put the new soa in
+ * \param[in] rrlist the rrlist to use
+ */
+void ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist);
+
+/**
+ * push an rrlist to a zone structure. This function use pointer
+ * copying, so the rr_list structure inside z is modified!
+ * \param[in] z the zone to add to
+ * \param[in] list the list to add
+ * \return a true on succes otherwise falsed
+ */
+bool ldns_zone_push_rr_list(ldns_zone *z, ldns_rr_list *list);
+
+/**
+ * push an single rr to a zone structure. This function use pointer
+ * copying, so the rr_list structure inside z is modified!
+ * \param[in] z the zone to add to
+ * \param[in] rr the rr to add
+ * \return a true on succes otherwise falsed
+ */
+bool ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr);
+
+/**
+ * Retrieve all resource records from the zone that are glue
+ * records. The resulting list does are pointer references
+ * to the zone's data.
+ *
+ * Due to the current zone implementation (as a list of rr's), this
+ * function is extremely slow. Another (probably better) way to do this
+ * is to use an ldns_dnssec_zone structure and the 
+ * ldns_dnssec_mark_and_get_glue() function.
+ *
+ * \param[in] z the zone to look for glue
+ * \return the rr_list with the glue
+ */
+ldns_rr_list *ldns_zone_glue_rr_list(const ldns_zone *z);
+
+/**
+ * Create a new zone from a file
+ * \param[out] z the new zone
+ * \param[in] *fp the filepointer to use
+ * \param[in] *origin the zones' origin
+ * \param[in] ttl default ttl to use
+ * \param[in] c default class to use (IN)
+ *
+ * \return ldns_status mesg with an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_zone_new_frm_fp(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c);
+
+/**
+ * Create a new zone from a file, keep track of the line numbering
+ * \param[out] z the new zone
+ * \param[in] *fp the filepointer to use
+ * \param[in] *origin the zones' origin
+ * \param[in] ttl default ttl to use
+ * \param[in] c default class to use (IN)
+ * \param[out] line_nr used for error msg, to get to the line number
+ *
+ * \return ldns_status mesg with an error or LDNS_STATUS_OK
+ */
+ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c, int *line_nr);
+
+/**
+ * Frees the allocated memory for the zone, and the rr_list structure in it
+ * \param[in] zone the zone to free
+ */
+void ldns_zone_free(ldns_zone *zone);
+
+/**
+ * Frees the allocated memory for the zone, the soa rr in it, 
+ * and the rr_list structure in it, including the rr's in that. etc.
+ * \param[in] zone the zone to free
+ */
+void ldns_zone_deep_free(ldns_zone *zone);
+
+/**
+ * Sort the rrs in a zone, with the current impl. this is slow
+ * \param[in] zone the zone to sort
+ */
+void ldns_zone_sort(ldns_zone *zone);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LDNS_ZONE_H */
diff --git a/ldns/src/buffer.c b/ldns/src/buffer.c
new file mode 100644
index 0000000..fc6c17e
--- /dev/null
+++ b/ldns/src/buffer.c
@@ -0,0 +1,177 @@
+/*
+ * buffer.c -- generic memory buffer .
+ *
+ * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+#include <ldns/buffer.h>
+
+ldns_buffer *
+ldns_buffer_new(size_t capacity)
+{
+	ldns_buffer *buffer = LDNS_MALLOC(ldns_buffer);
+
+	if (!buffer) {
+		return NULL;
+	}
+	
+	buffer->_data = (uint8_t *) LDNS_XMALLOC(uint8_t, capacity);
+	if (!buffer->_data) {
+		LDNS_FREE(buffer);
+		return NULL;
+	}
+	
+	buffer->_position = 0;
+	buffer->_limit = buffer->_capacity = capacity;
+	buffer->_fixed = 0;
+	buffer->_status = LDNS_STATUS_OK;
+	
+	ldns_buffer_invariant(buffer);
+	
+	return buffer;
+}
+
+void
+ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
+{
+	assert(data != NULL);
+
+	buffer->_position = 0; 
+	buffer->_limit = buffer->_capacity = size;
+	buffer->_fixed = 0;
+	buffer->_data = LDNS_XMALLOC(uint8_t, size);
+	if(!buffer->_data) {
+		buffer->_status = LDNS_STATUS_MEM_ERR;
+		return;
+	}
+	memcpy(buffer->_data, data, size);
+	buffer->_status = LDNS_STATUS_OK;
+	
+	ldns_buffer_invariant(buffer);
+}
+
+bool
+ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
+{
+	void *data;
+	
+	ldns_buffer_invariant(buffer);
+	assert(buffer->_position <= capacity);
+
+	data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
+	if (!data) {
+		buffer->_status = LDNS_STATUS_MEM_ERR;
+		return false;
+	} else {
+		buffer->_data = data;
+		buffer->_limit = buffer->_capacity = capacity;
+		return true;
+	}
+}
+
+bool
+ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
+{
+	ldns_buffer_invariant(buffer);
+	assert(!buffer->_fixed);
+	if (buffer->_capacity < buffer->_position + amount) {
+		size_t new_capacity = buffer->_capacity * 3 / 2;
+
+		if (new_capacity < buffer->_position + amount) {
+			new_capacity = buffer->_position + amount;
+		}
+		if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
+			buffer->_status = LDNS_STATUS_MEM_ERR;
+			return false;
+		}
+	}
+	buffer->_limit = buffer->_capacity;
+	return true;
+}
+
+int
+ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
+{
+	va_list args;
+	int written = 0;
+	size_t remaining;
+	
+	if (ldns_buffer_status_ok(buffer)) {
+		ldns_buffer_invariant(buffer);
+		assert(buffer->_limit == buffer->_capacity);
+
+		remaining = ldns_buffer_remaining(buffer);
+		va_start(args, format);
+		written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
+				    format, args);
+		va_end(args);
+		if (written == -1) {
+			buffer->_status = LDNS_STATUS_INTERNAL_ERR;
+			return -1;
+		} else if ((size_t) written >= remaining) {
+			if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
+				buffer->_status = LDNS_STATUS_MEM_ERR;
+				return -1;
+			}
+			va_start(args, format);
+			written = vsnprintf((char *) ldns_buffer_current(buffer),
+			    ldns_buffer_remaining(buffer), format, args);
+			va_end(args);
+			if (written == -1) {
+				buffer->_status = LDNS_STATUS_INTERNAL_ERR;
+				return -1;
+			}
+		}
+		buffer->_position += written;
+	}
+	return written;
+}
+
+void
+ldns_buffer_free(ldns_buffer *buffer)
+{
+	if (!buffer) {
+		return;
+	}
+
+	if (!buffer->_fixed)
+		LDNS_FREE(buffer->_data);
+
+	LDNS_FREE(buffer);
+}
+
+void *
+ldns_buffer_export(ldns_buffer *buffer)
+{
+	buffer->_fixed = 1;
+	return buffer->_data;
+}
+
+int
+ldns_bgetc(ldns_buffer *buffer)
+{
+	if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
+		ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
+		/* ldns_buffer_rewind(buffer);*/
+		return EOF;
+	}
+	return (int)ldns_buffer_read_u8(buffer);
+}
+
+void 
+ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
+{
+	size_t tocopy = ldns_buffer_limit(from);
+
+	if(tocopy > ldns_buffer_capacity(result))
+		tocopy = ldns_buffer_capacity(result);
+	ldns_buffer_clear(result);
+	ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
+	ldns_buffer_flip(result);
+}
diff --git a/ldns/src/compat/b64_ntop.c b/ldns/src/compat/b64_ntop.c
new file mode 100644
index 0000000..6895aca
--- /dev/null
+++ b/ldns/src/compat/b64_ntop.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+#include <ldns/config.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char Base64[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+   The following encoding technique is taken from RFC 1521 by Borenstein
+   and Freed.  It is reproduced here in a slightly edited form for
+   convenience.
+
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be
+   represented per printable character. (The extra 65th character, "=",
+   is used to signify a special processing function.)
+
+   The encoding process represents 24-bit groups of input bits as output
+   strings of 4 encoded characters. Proceeding from left to right, a
+   24-bit input group is formed by concatenating 3 8-bit input groups.
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each
+   of which is translated into a single digit in the base64 alphabet.
+
+   Each 6-bit group is used as an index into an array of 64 printable
+   characters. The character referenced by the index is placed in the
+   output string.
+
+                         Table 1: The Base64 Alphabet
+
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding
+          0 A            17 R            34 i            51 z
+          1 B            18 S            35 j            52 0
+          2 C            19 T            36 k            53 1
+          3 D            20 U            37 l            54 2
+          4 E            21 V            38 m            55 3
+          5 F            22 W            39 n            56 4
+          6 G            23 X            40 o            57 5
+          7 H            24 Y            41 p            58 6
+          8 I            25 Z            42 q            59 7
+          9 J            26 a            43 r            60 8
+         10 K            27 b            44 s            61 9
+         11 L            28 c            45 t            62 +
+         12 M            29 d            46 u            63 /
+         13 N            30 e            47 v
+         14 O            31 f            48 w         (pad) =
+         15 P            32 g            49 x
+         16 Q            33 h            50 y
+
+   Special processing is performed if fewer than 24 bits are available
+   at the end of the data being encoded.  A full encoding quantum is
+   always completed at the end of a quantity.  When fewer than 24 input
+   bits are available in an input group, zero bits are added (on the
+   right) to form an integral number of 6-bit groups.  Padding at the
+   end of the data is performed using the '=' character.
+
+   Since all base64 input is an integral number of octets, only the
+         -------------------------------------------------                       
+   following cases can arise:
+   
+       (1) the final quantum of encoding input is an integral
+           multiple of 24 bits; here, the final unit of encoded
+	   output will be an integral multiple of 4 characters
+	   with no "=" padding,
+       (2) the final quantum of encoding input is exactly 8 bits;
+           here, the final unit of encoded output will be two
+	   characters followed by two "=" padding characters, or
+       (3) the final quantum of encoding input is exactly 16 bits;
+           here, the final unit of encoded output will be three
+	   characters followed by one "=" padding character.
+   */
+
+int
+ldns_b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
+	size_t datalength = 0;
+	uint8_t input[3];
+	uint8_t output[4];
+	size_t i;
+	
+	if (srclength == 0) {
+		if (targsize > 0) {
+			target[0] = '\0';
+			return 0;
+		} else {
+			return -1;
+		}
+	}
+
+	while (2 < srclength) {
+		input[0] = *src++;
+		input[1] = *src++;
+		input[2] = *src++;
+		srclength -= 3;
+
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+		output[3] = input[2] & 0x3f;
+		assert(output[0] < 64);
+		assert(output[1] < 64);
+		assert(output[2] < 64);
+		assert(output[3] < 64);
+
+		if (datalength + 4 > targsize) {
+			return (-1);
+		}
+		target[datalength++] = Base64[output[0]];
+		target[datalength++] = Base64[output[1]];
+		target[datalength++] = Base64[output[2]];
+		target[datalength++] = Base64[output[3]];
+	}
+    
+	/* Now we worry about padding. */
+	if (0 != srclength) {
+		/* Get what's left. */
+		input[0] = input[1] = input[2] = (uint8_t) '\0';
+		for (i = 0; i < srclength; i++)
+			input[i] = *src++;
+	
+		output[0] = input[0] >> 2;
+		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+		assert(output[0] < 64);
+		assert(output[1] < 64);
+		assert(output[2] < 64);
+
+		if (datalength + 4 > targsize) {
+			return (-2);
+		}
+		target[datalength++] = Base64[output[0]];
+		target[datalength++] = Base64[output[1]];
+		if (srclength == 1) {
+			target[datalength++] = Pad64;
+		} else {
+			target[datalength++] = Base64[output[2]];
+		}
+		target[datalength++] = Pad64;
+	}
+	if (datalength >= targsize) {
+		return (-3);
+	}
+	target[datalength] = '\0';	/* Returned value doesn't count \0. */
+	return (int) (datalength);
+}
diff --git a/ldns/src/compat/b64_pton.c b/ldns/src/compat/b64_pton.c
new file mode 100644
index 0000000..18d8c8e
--- /dev/null
+++ b/ldns/src/compat/b64_pton.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 1996, 1998 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1995 by International Business Machines, Inc.
+ *
+ * International Business Machines, Inc. (hereinafter called IBM) grants
+ * permission under its copyrights to use, copy, modify, and distribute this
+ * Software with or without fee, provided that the above copyright notice and
+ * all paragraphs of this notice appear in all copies, and that the name of IBM
+ * not be used in connection with the marketing of any product incorporating
+ * the Software or modifications thereof, without specific, written prior
+ * permission.
+ *
+ * To the extent it has a right to do so, IBM grants an immunity from suit
+ * under its patents, if any, for the use, sale or manufacture of products to
+ * the extent that such products are used for performing Domain Name System
+ * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
+ * granted for any product per se or for any other function of any product.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
+ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
+ * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+#include <ldns/config.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char Base64[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char Pad64 = '=';
+
+/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
+   The following encoding technique is taken from RFC 1521 by Borenstein
+   and Freed.  It is reproduced here in a slightly edited form for
+   convenience.
+
+   A 65-character subset of US-ASCII is used, enabling 6 bits to be
+   represented per printable character. (The extra 65th character, "=",
+   is used to signify a special processing function.)
+
+   The encoding process represents 24-bit groups of input bits as output
+   strings of 4 encoded characters. Proceeding from left to right, a
+   24-bit input group is formed by concatenating 3 8-bit input groups.
+   These 24 bits are then treated as 4 concatenated 6-bit groups, each
+   of which is translated into a single digit in the base64 alphabet.
+
+   Each 6-bit group is used as an index into an array of 64 printable
+   characters. The character referenced by the index is placed in the
+   output string.
+
+                         Table 1: The Base64 Alphabet
+
+      Value Encoding  Value Encoding  Value Encoding  Value Encoding
+          0 A            17 R            34 i            51 z
+          1 B            18 S            35 j            52 0
+          2 C            19 T            36 k            53 1
+          3 D            20 U            37 l            54 2
+          4 E            21 V            38 m            55 3
+          5 F            22 W            39 n            56 4
+          6 G            23 X            40 o            57 5
+          7 H            24 Y            41 p            58 6
+          8 I            25 Z            42 q            59 7
+          9 J            26 a            43 r            60 8
+         10 K            27 b            44 s            61 9
+         11 L            28 c            45 t            62 +
+         12 M            29 d            46 u            63 /
+         13 N            30 e            47 v
+         14 O            31 f            48 w         (pad) =
+         15 P            32 g            49 x
+         16 Q            33 h            50 y
+
+   Special processing is performed if fewer than 24 bits are available
+   at the end of the data being encoded.  A full encoding quantum is
+   always completed at the end of a quantity.  When fewer than 24 input
+   bits are available in an input group, zero bits are added (on the
+   right) to form an integral number of 6-bit groups.  Padding at the
+   end of the data is performed using the '=' character.
+
+   Since all base64 input is an integral number of octets, only the
+         -------------------------------------------------                       
+   following cases can arise:
+   
+       (1) the final quantum of encoding input is an integral
+           multiple of 24 bits; here, the final unit of encoded
+	   output will be an integral multiple of 4 characters
+	   with no "=" padding,
+       (2) the final quantum of encoding input is exactly 8 bits;
+           here, the final unit of encoded output will be two
+	   characters followed by two "=" padding characters, or
+       (3) the final quantum of encoding input is exactly 16 bits;
+           here, the final unit of encoded output will be three
+	   characters followed by one "=" padding character.
+   */
+
+/* skips all whitespace anywhere.
+   converts characters, four at a time, starting at (or after)
+   src from base - 64 numbers into three 8 bit bytes in the target area.
+   it returns the number of data bytes stored at the target, or -1 on error.
+ */
+
+int
+ldns_b64_pton(char const *origsrc, uint8_t *target, size_t targsize)
+{
+	unsigned char const* src = (unsigned char*)origsrc;
+	int tarindex, state, ch;
+	char *pos;
+
+	state = 0;
+	tarindex = 0;
+
+	if (strlen(origsrc) == 0) {
+		return 0;
+	}
+
+	while ((ch = *src++) != '\0') {
+		if (isspace((unsigned char)ch))        /* Skip whitespace anywhere. */
+			continue;
+
+		if (ch == Pad64)
+			break;
+
+		pos = strchr(Base64, ch);
+		if (pos == 0) {
+			/* A non-base64 character. */
+			return (-1);
+		}
+
+		switch (state) {
+		case 0:
+			if (target) {
+				if ((size_t)tarindex >= targsize)
+					return (-1);
+				target[tarindex] = (pos - Base64) << 2;
+			}
+			state = 1;
+			break;
+		case 1:
+			if (target) {
+				if ((size_t)tarindex + 1 >= targsize)
+					return (-1);
+				target[tarindex]   |=  (pos - Base64) >> 4;
+				target[tarindex+1]  = ((pos - Base64) & 0x0f)
+							<< 4 ;
+			}
+			tarindex++;
+			state = 2;
+			break;
+		case 2:
+			if (target) {
+				if ((size_t)tarindex + 1 >= targsize)
+					return (-1);
+				target[tarindex]   |=  (pos - Base64) >> 2;
+				target[tarindex+1]  = ((pos - Base64) & 0x03)
+							<< 6;
+			}
+			tarindex++;
+			state = 3;
+			break;
+		case 3:
+			if (target) {
+				if ((size_t)tarindex >= targsize)
+					return (-1);
+				target[tarindex] |= (pos - Base64);
+			}
+			tarindex++;
+			state = 0;
+			break;
+		default:
+			abort();
+		}
+	}
+
+	/*
+	 * We are done decoding Base-64 chars.  Let's see if we ended
+	 * on a byte boundary, and/or with erroneous trailing characters.
+	 */
+
+	if (ch == Pad64) {		/* We got a pad char. */
+		ch = *src++;		/* Skip it, get next. */
+		switch (state) {
+		case 0:		/* Invalid = in first position */
+		case 1:		/* Invalid = in second position */
+			return (-1);
+
+		case 2:		/* Valid, means one byte of info */
+			/* Skip any number of spaces. */
+			for ((void)NULL; ch != '\0'; ch = *src++)
+				if (!isspace((unsigned char)ch))
+					break;
+			/* Make sure there is another trailing = sign. */
+			if (ch != Pad64)
+				return (-1);
+			ch = *src++;		/* Skip the = */
+			/* Fall through to "single trailing =" case. */
+			/* FALLTHROUGH */
+
+		case 3:		/* Valid, means two bytes of info */
+			/*
+			 * We know this char is an =.  Is there anything but
+			 * whitespace after it?
+			 */
+			for ((void)NULL; ch != '\0'; ch = *src++)
+				if (!isspace((unsigned char)ch))
+					return (-1);
+
+			/*
+			 * Now make sure for cases 2 and 3 that the "extra"
+			 * bits that slopped past the last full byte were
+			 * zeros.  If we don't check them, they become a
+			 * subliminal channel.
+			 */
+			if (target && target[tarindex] != 0)
+				return (-1);
+		}
+	} else {
+		/*
+		 * We ended by seeing the end of the string.  Make sure we
+		 * have no partial bytes lying around.
+		 */
+		if (state != 0)
+			return (-1);
+	}
+
+	return (tarindex);
+}
diff --git a/ldns/src/compat/strlcpy.c b/ldns/src/compat/strlcpy.c
new file mode 100644
index 0000000..d6c34c1
--- /dev/null
+++ b/ldns/src/compat/strlcpy.c
@@ -0,0 +1,57 @@
+/* from openssh 4.3p2 compat/strlcpy.c */
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
+
+#include <ldns/config.h>
+#ifndef HAVE_STRLCPY
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+	char *d = dst;
+	const char *s = src;
+	size_t n = siz;
+
+	/* Copy as many bytes as will fit */
+	if (n != 0 && --n != 0) {
+		do {
+			if ((*d++ = *s++) == 0)
+				break;
+		} while (--n != 0);
+	}
+
+	/* Not enough room in dst, add NUL and traverse rest of src */
+	if (n == 0) {
+		if (siz != 0)
+			*d = '\0';		/* NUL-terminate dst */
+		while (*s++)
+			;
+	}
+
+	return(s - src - 1);	/* count does not include NUL */
+}
+
+#endif /* !HAVE_STRLCPY */
diff --git a/ldns/src/dane.c b/ldns/src/dane.c
new file mode 100644
index 0000000..675dfa8
--- /dev/null
+++ b/ldns/src/dane.c
@@ -0,0 +1,748 @@
+/*
+ * Verify or create TLS authentication with DANE (RFC6698)
+ *
+ * (c) NLnetLabs 2012
+ *
+ * See the file LICENSE for the license.
+ *
+ */
+
+#include <ldns/config.h>
+#ifdef USE_DANE
+
+#include <ldns/ldns.h>
+#include <ldns/dane.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_SSL
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#endif
+
+ldns_status
+ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner, const ldns_rdf* name,
+		uint16_t port, ldns_dane_transport transport)
+{
+	char buf[LDNS_MAX_DOMAINLEN];
+	size_t s;
+
+	assert(tlsa_owner != NULL);
+	assert(name != NULL);
+	assert(ldns_rdf_get_type(name) == LDNS_RDF_TYPE_DNAME);
+
+	s = (size_t)snprintf(buf, LDNS_MAX_DOMAINLEN, "X_%d", (int)port);
+	buf[0] = (char)(s - 1);
+
+	switch(transport) {
+	case LDNS_DANE_TRANSPORT_TCP:
+		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_tcp");
+		break;
+	
+	case LDNS_DANE_TRANSPORT_UDP:
+		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_udp");
+		break;
+
+	case LDNS_DANE_TRANSPORT_SCTP:
+		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\005_sctp");
+		break;
+	
+	default:
+		return LDNS_STATUS_DANE_UNKNOWN_TRANSPORT;
+	}
+	if (s + ldns_rdf_size(name) > LDNS_MAX_DOMAINLEN) {
+		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+	}
+	memcpy(buf + s, ldns_rdf_data(name), ldns_rdf_size(name));
+	*tlsa_owner = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
+			s + ldns_rdf_size(name), buf);
+	if (*tlsa_owner == NULL) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
+
+
+#ifdef HAVE_SSL
+ldns_status
+ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
+		ldns_tlsa_selector      selector,
+		ldns_tlsa_matching_type matching_type)
+{
+	unsigned char* buf = NULL;
+	size_t len;
+
+	X509_PUBKEY* xpubkey;
+	EVP_PKEY* epubkey;
+
+	unsigned char* digest;
+
+	assert(rdf != NULL);
+	assert(cert != NULL);
+
+	switch(selector) {
+	case LDNS_TLSA_SELECTOR_FULL_CERTIFICATE:
+
+		len = (size_t)i2d_X509(cert, &buf);
+		break;
+
+	case LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO:
+
+#ifndef S_SPLINT_S
+		xpubkey = X509_get_X509_PUBKEY(cert);
+#endif
+		if (! xpubkey) {
+			return LDNS_STATUS_SSL_ERR;
+		}
+		epubkey = X509_PUBKEY_get(xpubkey);
+		if (! epubkey) {
+			return LDNS_STATUS_SSL_ERR;
+		}
+		len = (size_t)i2d_PUBKEY(epubkey, &buf);
+		break;
+	
+	default:
+		return LDNS_STATUS_DANE_UNKNOWN_SELECTOR;
+	}
+
+	switch(matching_type) {
+	case LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED:
+
+		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, len, buf);
+		
+		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+		break;
+	
+	case LDNS_TLSA_MATCHING_TYPE_SHA256:
+
+		digest = LDNS_XMALLOC(unsigned char, LDNS_SHA256_DIGEST_LENGTH);
+		if (digest == NULL) {
+			LDNS_FREE(buf);
+			return LDNS_STATUS_MEM_ERR;
+		}
+		(void) ldns_sha256(buf, (unsigned int)len, digest);
+		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, LDNS_SHA256_DIGEST_LENGTH,
+				digest);
+		LDNS_FREE(buf);
+
+		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+		break;
+
+	case LDNS_TLSA_MATCHING_TYPE_SHA512:
+
+		digest = LDNS_XMALLOC(unsigned char, LDNS_SHA512_DIGEST_LENGTH);
+		if (digest == NULL) {
+			LDNS_FREE(buf);
+			return LDNS_STATUS_MEM_ERR;
+		}
+		(void) ldns_sha512(buf, (unsigned int)len, digest);
+		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, LDNS_SHA512_DIGEST_LENGTH,
+				digest);
+		LDNS_FREE(buf);
+
+		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+		break;
+	
+	default:
+		LDNS_FREE(buf);
+		return LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE;
+	}
+}
+
+
+/* Ordinary PKIX validation of cert (with extra_certs to help)
+ * against the CA's in store
+ */
+static ldns_status
+ldns_dane_pkix_validate(X509* cert, STACK_OF(X509)* extra_certs,
+		X509_STORE* store)
+{
+	X509_STORE_CTX* vrfy_ctx;
+	ldns_status s;
+
+	if (! store) {
+		return LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+	}
+	vrfy_ctx = X509_STORE_CTX_new();
+	if (! vrfy_ctx) {
+
+		return LDNS_STATUS_SSL_ERR;
+
+	} else if (X509_STORE_CTX_init(vrfy_ctx, store,
+				cert, extra_certs) != 1) {
+		s = LDNS_STATUS_SSL_ERR;
+
+	} else if (X509_verify_cert(vrfy_ctx) == 1) {
+
+		s = LDNS_STATUS_OK;
+
+	} else {
+		s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+	}
+	X509_STORE_CTX_free(vrfy_ctx);
+	return s;
+}
+
+
+/* Orinary PKIX validation of cert (with extra_certs to help)
+ * against the CA's in store, but also return the validation chain.
+ */
+static ldns_status
+ldns_dane_pkix_validate_and_get_chain(STACK_OF(X509)** chain, X509* cert,
+		STACK_OF(X509)* extra_certs, X509_STORE* store)
+{
+	ldns_status s;
+	X509_STORE* empty_store = NULL;
+	X509_STORE_CTX* vrfy_ctx;
+
+	assert(chain != NULL);
+
+	if (! store) {
+		store = empty_store = X509_STORE_new();
+	}
+	s = LDNS_STATUS_SSL_ERR;
+	vrfy_ctx = X509_STORE_CTX_new();
+	if (! vrfy_ctx) {
+
+		goto exit_free_empty_store;
+
+	} else if (X509_STORE_CTX_init(vrfy_ctx, store,
+					cert, extra_certs) != 1) {
+		goto exit_free_vrfy_ctx;
+
+	} else if (X509_verify_cert(vrfy_ctx) == 1) {
+
+		s = LDNS_STATUS_OK;
+
+	} else {
+		s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+	}
+	*chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
+	if (! *chain) {
+		s = LDNS_STATUS_SSL_ERR;
+	}
+
+exit_free_vrfy_ctx:
+	X509_STORE_CTX_free(vrfy_ctx);
+
+exit_free_empty_store:
+	if (empty_store) {
+		X509_STORE_free(empty_store);
+	}
+	return s;
+}
+
+
+/* Return the validation chain that can be build out of cert, with extra_certs.
+ */
+static ldns_status
+ldns_dane_pkix_get_chain(STACK_OF(X509)** chain,
+		X509* cert, STACK_OF(X509)* extra_certs)
+{
+	ldns_status s;
+	X509_STORE* empty_store = NULL;
+	X509_STORE_CTX* vrfy_ctx;
+
+	assert(chain != NULL);
+
+	empty_store = X509_STORE_new();
+	s = LDNS_STATUS_SSL_ERR;
+	vrfy_ctx = X509_STORE_CTX_new();
+	if (! vrfy_ctx) {
+
+		goto exit_free_empty_store;
+
+	} else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
+					cert, extra_certs) != 1) {
+		goto exit_free_vrfy_ctx;
+	}
+	(void) X509_verify_cert(vrfy_ctx);
+	*chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
+	if (! *chain) {
+		s = LDNS_STATUS_SSL_ERR;
+	} else {
+		s = LDNS_STATUS_OK;
+	}
+exit_free_vrfy_ctx:
+	X509_STORE_CTX_free(vrfy_ctx);
+
+exit_free_empty_store:
+	X509_STORE_free(empty_store);
+	return s;
+}
+
+
+/* Pop n+1 certs and return the last popped.
+ */
+static ldns_status
+ldns_dane_get_nth_cert_from_validation_chain(
+		X509** cert, STACK_OF(X509)* chain, int n, bool ca)
+{
+	if (n >= sk_X509_num(chain) || n < 0) {
+		return LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE;
+	}
+	*cert = sk_X509_pop(chain);
+	while (n-- > 0) {
+		X509_free(*cert);
+		*cert = sk_X509_pop(chain);
+	}
+	if (ca && ! X509_check_ca(*cert)) {
+		return LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
+	}
+	return LDNS_STATUS_OK;
+}
+
+
+/* Create validation chain with cert and extra_certs and returns the last
+ * self-signed (if present).
+ */
+static ldns_status
+ldns_dane_pkix_get_last_self_signed(X509** out_cert,
+		X509* cert, STACK_OF(X509)* extra_certs)
+{
+	ldns_status s;
+	X509_STORE* empty_store = NULL;
+	X509_STORE_CTX* vrfy_ctx;
+
+	assert(out_cert != NULL);
+
+	empty_store = X509_STORE_new();
+	s = LDNS_STATUS_SSL_ERR;
+	vrfy_ctx = X509_STORE_CTX_new();
+	if (! vrfy_ctx) {
+		goto exit_free_empty_store;
+
+	} else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
+					cert, extra_certs) != 1) {
+		goto exit_free_vrfy_ctx;
+
+	}
+	(void) X509_verify_cert(vrfy_ctx);
+	if (vrfy_ctx->error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
+	    vrfy_ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT){
+
+		*out_cert = X509_STORE_CTX_get_current_cert( vrfy_ctx);
+		s = LDNS_STATUS_OK;
+	} else {
+		s = LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR;
+	}
+exit_free_vrfy_ctx:
+	X509_STORE_CTX_free(vrfy_ctx);
+
+exit_free_empty_store:
+	X509_STORE_free(empty_store);
+	return s;
+}
+
+
+ldns_status
+ldns_dane_select_certificate(X509** selected_cert,
+		X509* cert, STACK_OF(X509)* extra_certs,
+		X509_STORE* pkix_validation_store,
+		ldns_tlsa_certificate_usage cert_usage, int offset)
+{
+	ldns_status s;
+	STACK_OF(X509)* pkix_validation_chain = NULL;
+
+	assert(selected_cert != NULL);
+	assert(cert != NULL);
+
+	/* With PKIX validation explicitely turned off (pkix_validation_store
+	 *  == NULL), treat the "CA constraint" and "Service certificate
+	 * constraint" the same as "Trust anchor assertion" and "Domain issued
+	 * certificate" respectively.
+	 */
+	if (pkix_validation_store == NULL) {
+		switch (cert_usage) {
+
+		case LDNS_TLSA_USAGE_CA_CONSTRAINT:
+
+			cert_usage = LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION;
+			break;
+
+		case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
+
+			cert_usage = LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE;
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	/* Now what to do with each Certificate usage...
+	 */
+	switch (cert_usage) {
+
+	case LDNS_TLSA_USAGE_CA_CONSTRAINT:
+
+		s = ldns_dane_pkix_validate_and_get_chain(
+				&pkix_validation_chain,
+				cert, extra_certs,
+				pkix_validation_store);
+		if (! pkix_validation_chain) {
+			return s;
+		}
+		if (s == LDNS_STATUS_OK) {
+			if (offset == -1) {
+				offset = 0;
+			}
+			s = ldns_dane_get_nth_cert_from_validation_chain(
+					selected_cert, pkix_validation_chain,
+					offset, true);
+		}
+		sk_X509_pop_free(pkix_validation_chain, X509_free);
+		return s;
+		break;
+
+
+	case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
+
+		*selected_cert = cert;
+		return ldns_dane_pkix_validate(cert, extra_certs,
+				pkix_validation_store);
+		break;
+
+
+	case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
+
+		if (offset == -1) {
+			s = ldns_dane_pkix_get_last_self_signed(
+					selected_cert, cert, extra_certs);
+			return s;
+		} else {
+			s = ldns_dane_pkix_get_chain(
+					&pkix_validation_chain,
+					cert, extra_certs);
+			if (s == LDNS_STATUS_OK) {
+				s =
+				ldns_dane_get_nth_cert_from_validation_chain(
+					selected_cert, pkix_validation_chain,
+					offset, false);
+			} else if (! pkix_validation_chain) {
+				return s;
+			}
+			sk_X509_pop_free(pkix_validation_chain, X509_free);
+			return s;
+		}
+		break;
+
+
+	case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
+
+		*selected_cert = cert;
+		return LDNS_STATUS_OK;
+		break;
+	
+	default:
+		return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
+		break;
+	}
+}
+
+
+ldns_status
+ldns_dane_create_tlsa_rr(ldns_rr** tlsa,
+		ldns_tlsa_certificate_usage certificate_usage,
+		ldns_tlsa_selector          selector,
+		ldns_tlsa_matching_type     matching_type,
+		X509* cert)
+{
+	ldns_rdf* rdf;
+	ldns_status s;
+
+	assert(tlsa != NULL);
+	assert(cert != NULL);
+
+	/* create rr */
+	*tlsa = ldns_rr_new_frm_type(LDNS_RR_TYPE_TLSA);
+	if (*tlsa == NULL) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
+			(uint8_t)certificate_usage);
+	if (rdf == NULL) {
+		goto memerror;
+	}
+	(void) ldns_rr_set_rdf(*tlsa, rdf, 0);
+
+	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)selector);
+	if (rdf == NULL) {
+		goto memerror;
+	}
+	(void) ldns_rr_set_rdf(*tlsa, rdf, 1);
+
+	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)matching_type);
+	if (rdf == NULL) {
+		goto memerror;
+	}
+	(void) ldns_rr_set_rdf(*tlsa, rdf, 2);
+
+	s = ldns_dane_cert2rdf(&rdf, cert, selector, matching_type);
+	if (s == LDNS_STATUS_OK) {
+		(void) ldns_rr_set_rdf(*tlsa, rdf, 3);
+		return LDNS_STATUS_OK;
+	}
+	ldns_rr_free(*tlsa);
+	*tlsa = NULL;
+	return s;
+
+memerror:
+	ldns_rr_free(*tlsa);
+	*tlsa = NULL;
+	return LDNS_STATUS_MEM_ERR;
+}
+
+
+/* Return tlsas that actually are TLSA resource records with known values
+ * for the Certificate usage, Selector and Matching type rdata fields.
+ */
+static ldns_rr_list*
+ldns_dane_filter_unusable_records(const ldns_rr_list* tlsas)
+{
+	size_t i;
+	ldns_rr_list* r = ldns_rr_list_new();
+	ldns_rr* tlsa_rr;
+
+	if (! r) {
+		return NULL;
+	}
+	for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
+		tlsa_rr = ldns_rr_list_rr(tlsas, i);
+		if (ldns_rr_get_type(tlsa_rr) == LDNS_RR_TYPE_TLSA &&
+		    ldns_rr_rd_count(tlsa_rr) == 4 &&
+		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0)) <= 3 &&
+		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1)) <= 1 &&
+		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2)) <= 2) {
+
+			if (! ldns_rr_list_push_rr(r, tlsa_rr)) {
+				ldns_rr_list_free(r);
+				return NULL;
+			}
+		}
+	}
+	return r;
+}
+
+
+/* Return whether cert/selector/matching_type matches data.
+ */
+static ldns_status
+ldns_dane_match_cert_with_data(X509* cert, ldns_tlsa_selector selector,
+		ldns_tlsa_matching_type matching_type, ldns_rdf* data)
+{
+	ldns_status s;
+	ldns_rdf* match_data;
+
+	s = ldns_dane_cert2rdf(&match_data, cert, selector, matching_type);
+	if (s == LDNS_STATUS_OK) {
+		if (ldns_rdf_compare(data, match_data) != 0) {
+			s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
+		}
+		ldns_rdf_free(match_data);
+	}
+	return s;
+}
+
+
+/* Return whether any certificate from the chain with selector/matching_type
+ * matches data.
+ * ca should be true if the certificate has to be a CA certificate too.
+ */
+static ldns_status
+ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain,
+		ldns_tlsa_selector      selector,
+		ldns_tlsa_matching_type matching_type,
+		ldns_rdf* data, bool ca)
+{
+	ldns_status s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
+	size_t n, i;
+	X509* cert;
+
+	n = (size_t)sk_X509_num(chain);
+	for (i = 0; i < n; i++) {
+		cert = sk_X509_pop(chain);
+		if (! cert) {
+			s = LDNS_STATUS_SSL_ERR;
+			break;
+		}
+		s = ldns_dane_match_cert_with_data(cert,
+				selector, matching_type, data);
+		if (ca && s == LDNS_STATUS_OK && ! X509_check_ca(cert)) {
+			s = LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
+		}
+		X509_free(cert);
+		if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH) {
+			break;
+		}
+		/* when s == LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
+		 * try to match the next certificate
+		 */
+	}
+	return s;
+}
+
+
+ldns_status
+ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
+		X509* cert, STACK_OF(X509)* extra_certs,
+		X509_STORE* pkix_validation_store)
+{
+	ldns_status s;
+
+	STACK_OF(X509)* pkix_validation_chain = NULL;
+
+	ldns_tlsa_certificate_usage cert_usage;
+	ldns_tlsa_selector          selector;
+	ldns_tlsa_matching_type     matching_type;
+	ldns_rdf*                   data;
+
+	if (! tlsa_rr) {
+		/* No TLSA, so regular PKIX validation
+		 */
+		return ldns_dane_pkix_validate(cert, extra_certs,
+				pkix_validation_store);
+	}
+	cert_usage    = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0));
+	selector      = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1));
+	matching_type = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2));
+	data          =                      ldns_rr_rdf(tlsa_rr, 3) ;
+
+	switch (cert_usage) {
+	case LDNS_TLSA_USAGE_CA_CONSTRAINT:
+		s = ldns_dane_pkix_validate_and_get_chain(
+				&pkix_validation_chain, 
+				cert, extra_certs,
+				pkix_validation_store);
+		if (! pkix_validation_chain) {
+			return s;
+		}
+		if (s == LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
+			/*
+			 * NO PKIX validation. We still try to match *any*
+			 * certificate from the chain, so we return
+			 * TLSA errors over PKIX errors.
+			 *
+			 * i.e. When the TLSA matches no certificate, we return
+			 * TLSA_DID_NOT_MATCH and not PKIX_DID_NOT_VALIDATE
+			 */
+			s = ldns_dane_match_any_cert_with_data(
+					pkix_validation_chain,
+					selector, matching_type, data, true);
+
+			if (s == LDNS_STATUS_OK) {
+				/* A TLSA record did match a cert from the
+				 * chain, thus the error is failed PKIX
+				 * validation.
+				 */
+				s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
+			}
+
+		} else if (s == LDNS_STATUS_OK) { 
+			/* PKIX validated, does the TLSA match too? */
+
+			s = ldns_dane_match_any_cert_with_data(
+					pkix_validation_chain,
+					selector, matching_type, data, true);
+		}
+		sk_X509_pop_free(pkix_validation_chain, X509_free);
+		return s;
+		break;
+
+	case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
+		s = ldns_dane_match_cert_with_data(cert,
+				selector, matching_type, data);
+
+		if (s == LDNS_STATUS_OK) {
+			return ldns_dane_pkix_validate(cert, extra_certs,
+					pkix_validation_store);
+		}
+		return s;
+		break;
+
+	case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
+		s = ldns_dane_pkix_get_chain(&pkix_validation_chain,
+				cert, extra_certs);
+
+		if (s == LDNS_STATUS_OK) {
+			s = ldns_dane_match_any_cert_with_data(
+					pkix_validation_chain,
+					selector, matching_type, data, false);
+
+		} else if (! pkix_validation_chain) {
+			return s;
+		}
+		sk_X509_pop_free(pkix_validation_chain, X509_free);
+		return s;
+		break;
+
+	case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
+		return ldns_dane_match_cert_with_data(cert,
+				selector, matching_type, data);
+		break;
+
+	default:
+		break;
+	}
+	return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
+}
+
+
+ldns_status
+ldns_dane_verify(ldns_rr_list* tlsas,
+		X509* cert, STACK_OF(X509)* extra_certs,
+		X509_STORE* pkix_validation_store)
+{
+	size_t i;
+	ldns_rr* tlsa_rr;
+	ldns_status s = LDNS_STATUS_OK, ps;
+
+	assert(cert != NULL);
+
+	if (tlsas && ldns_rr_list_rr_count(tlsas) > 0) {
+		tlsas = ldns_dane_filter_unusable_records(tlsas);
+		if (! tlsas) {
+			return LDNS_STATUS_MEM_ERR;
+		}
+	}
+	if (! tlsas || ldns_rr_list_rr_count(tlsas) == 0) {
+		/* No TLSA's, so regular PKIX validation
+		 */
+		return ldns_dane_pkix_validate(cert, extra_certs,
+				pkix_validation_store);
+	} else {
+		for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
+			tlsa_rr = ldns_rr_list_rr(tlsas, i);
+			ps = s;
+			s = ldns_dane_verify_rr(tlsa_rr, cert, extra_certs,
+					pkix_validation_store);
+
+			if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH &&
+			    s != LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
+
+				/* which would be LDNS_STATUS_OK (match)
+				 * or some fatal error preventing use from
+				 * trying the next TLSA record.
+				 */
+				break;
+			}
+			s = (s > ps ? s : ps); /* prefer PKIX_DID_NOT_VALIDATE
+						* over   TLSA_DID_NOT_MATCH
+						*/
+		}
+		ldns_rr_list_free(tlsas);
+	}
+	return s;
+}
+#endif /* HAVE_SSL */
+#endif /* USE_DANE */
diff --git a/ldns/src/dname.c b/ldns/src/dname.c
new file mode 100644
index 0000000..55aba5d
--- /dev/null
+++ b/ldns/src/dname.c
@@ -0,0 +1,598 @@
+/*
+ * dname.c
+ *
+ * dname specific rdata implementations
+ * A dname is a rdf structure with type LDNS_RDF_TYPE_DNAME
+ * It is not a /real/ type! All function must therefor check
+ * for LDNS_RDF_TYPE_DNAME.
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+/* Returns whether the last label in the name is a root label (a empty label).
+ * Note that it is not enough to just test the last character to be 0,
+ * because it may be part of the last label itself.
+ */
+static bool
+ldns_dname_last_label_is_root_label(const ldns_rdf* dname)
+{
+	size_t src_pos;
+	size_t len = 0;
+
+	for (src_pos = 0; src_pos < ldns_rdf_size(dname); src_pos += len + 1) {
+		len = ldns_rdf_data(dname)[src_pos];
+	}
+	assert(src_pos == ldns_rdf_size(dname));
+
+	return src_pos > 0 && len == 0;
+}
+
+ldns_rdf *
+ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
+{
+	ldns_rdf *new;
+	uint16_t new_size;
+	uint8_t *buf;
+	uint16_t left_size;
+
+	if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
+			ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
+		return NULL;
+	}
+
+	/* remove root label if it is present at the end of the left
+	 * rd, by reducing the size with 1
+	 */
+	left_size = ldns_rdf_size(rd1);
+	if (ldns_dname_last_label_is_root_label(rd1)) {
+		left_size--;
+	}
+
+	/* we overwrite the nullbyte of rd1 */
+	new_size = left_size + ldns_rdf_size(rd2);
+	buf = LDNS_XMALLOC(uint8_t, new_size);
+	if (!buf) {
+		return NULL;
+	}
+
+	/* put the two dname's after each other */
+	memcpy(buf, ldns_rdf_data(rd1), left_size);
+	memcpy(buf + left_size, ldns_rdf_data(rd2), ldns_rdf_size(rd2));
+
+	new = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, new_size, buf);
+
+	LDNS_FREE(buf);
+	return new;
+}
+
+ldns_status
+ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
+{
+	uint16_t left_size;
+	uint16_t size;
+	uint8_t* newd;
+
+	if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
+			ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* remove root label if it is present at the end of the left
+	 * rd, by reducing the size with 1
+	 */
+	left_size = ldns_rdf_size(rd1);
+	if (ldns_dname_last_label_is_root_label(rd1)) {
+		left_size--;
+	}
+
+	size = left_size + ldns_rdf_size(rd2);
+	newd = LDNS_XREALLOC(ldns_rdf_data(rd1), uint8_t, size);
+	if(!newd) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	ldns_rdf_set_data(rd1, newd);
+	memcpy(ldns_rdf_data(rd1) + left_size, ldns_rdf_data(rd2),
+			ldns_rdf_size(rd2));
+	ldns_rdf_set_size(rd1, size);
+
+	return LDNS_STATUS_OK;
+}
+
+ldns_rdf*
+ldns_dname_reverse(const ldns_rdf *dname)
+{
+	size_t rd_size;
+	uint8_t* buf;
+	ldns_rdf* new;
+	size_t src_pos;
+	size_t len ;
+
+	assert(ldns_rdf_get_type(dname) == LDNS_RDF_TYPE_DNAME);
+	
+	rd_size = ldns_rdf_size(dname);
+	buf = LDNS_XMALLOC(uint8_t, rd_size);
+	if (! buf) {
+		return NULL;
+	}
+	new = ldns_rdf_new(LDNS_RDF_TYPE_DNAME, rd_size, buf);
+	if (! new) {
+		LDNS_FREE(buf);
+		return NULL;
+	}
+	
+	/* If dname ends in a root label, the reverse should too.
+	 */
+	if (ldns_dname_last_label_is_root_label(dname)) {
+		buf[rd_size - 1] = 0;
+		rd_size -= 1;
+	}
+	for (src_pos = 0; src_pos < rd_size; src_pos += len + 1) {
+		len = ldns_rdf_data(dname)[src_pos];
+		memcpy(&buf[rd_size - src_pos - len - 1],
+				&ldns_rdf_data(dname)[src_pos], len + 1);
+	}
+	return new;
+}
+
+ldns_rdf *
+ldns_dname_clone_from(const ldns_rdf *d, uint16_t n)
+{
+	uint8_t *data;
+	uint8_t label_size;
+	size_t data_size;
+
+	if (!d ||
+	    ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME ||
+	    ldns_dname_label_count(d) < n) {
+		return NULL;
+	}
+
+	data = ldns_rdf_data(d);
+	data_size = ldns_rdf_size(d);
+	while (n > 0) {
+		label_size = data[0] + 1;
+		data += label_size;
+		if (data_size < label_size) {
+			/* this label is very broken */
+			return NULL;
+		}
+		data_size -= label_size;
+		n--;
+	}
+
+	return ldns_dname_new_frm_data(data_size, data);
+}
+
+ldns_rdf *
+ldns_dname_left_chop(const ldns_rdf *d)
+{
+	uint8_t label_pos;
+	ldns_rdf *chop;
+
+	if (!d) {
+		return NULL;
+	}
+
+	if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
+		return NULL;
+	}
+	if (ldns_dname_label_count(d) == 0) {
+		/* root label */
+		return NULL;
+	}
+	/* 05blaat02nl00 */
+	label_pos = ldns_rdf_data(d)[0];
+
+	chop = ldns_dname_new_frm_data(ldns_rdf_size(d) - label_pos - 1,
+			ldns_rdf_data(d) + label_pos + 1);
+	return chop;
+}
+
+uint8_t
+ldns_dname_label_count(const ldns_rdf *r)
+{
+        uint16_t src_pos;
+        uint16_t len;
+        uint8_t i;
+        size_t r_size;
+
+	if (!r) {
+		return 0;
+	}
+
+	i = 0;
+	src_pos = 0;
+	r_size = ldns_rdf_size(r);
+
+	if (ldns_rdf_get_type(r) != LDNS_RDF_TYPE_DNAME) {
+		return 0;
+	} else {
+		len = ldns_rdf_data(r)[src_pos]; /* start of the label */
+
+		/* single root label */
+		if (1 == r_size) {
+			return 0;
+		} else {
+			while ((len > 0) && src_pos < r_size) {
+				src_pos++;
+				src_pos += len;
+				len = ldns_rdf_data(r)[src_pos];
+				i++;
+			}
+		}
+	}
+	return i;
+}
+
+ldns_rdf *
+ldns_dname_new(uint16_t s, void *d)
+{
+        ldns_rdf *rd;
+
+        rd = LDNS_MALLOC(ldns_rdf);
+        if (!rd) {
+                return NULL;
+        }
+        ldns_rdf_set_size(rd, s);
+        ldns_rdf_set_type(rd, LDNS_RDF_TYPE_DNAME);
+        ldns_rdf_set_data(rd, d);
+        return rd;
+}
+
+ldns_rdf *
+ldns_dname_new_frm_str(const char *str)
+{
+	return ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, str);
+}
+
+ldns_rdf *
+ldns_dname_new_frm_data(uint16_t size, const void *data)
+{
+	return ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, size, data);
+}
+
+void
+ldns_dname2canonical(const ldns_rdf *rd)
+{
+	uint8_t *rdd;
+	uint16_t i;
+
+	if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_DNAME) {
+		return;
+	}
+
+	rdd = (uint8_t*)ldns_rdf_data(rd);
+	for (i = 0; i < ldns_rdf_size(rd); i++, rdd++) {
+		*rdd = (uint8_t)LDNS_DNAME_NORMALIZE((int)*rdd);
+	}
+}
+
+bool
+ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
+{
+	uint8_t sub_lab;
+	uint8_t par_lab;
+	int8_t i, j;
+	ldns_rdf *tmp_sub = NULL;
+	ldns_rdf *tmp_par = NULL;
+    ldns_rdf *sub_clone;
+    ldns_rdf *parent_clone;
+    bool result = true;
+
+	if (ldns_rdf_get_type(sub) != LDNS_RDF_TYPE_DNAME ||
+			ldns_rdf_get_type(parent) != LDNS_RDF_TYPE_DNAME ||
+			ldns_rdf_compare(sub, parent) == 0) {
+		return false;
+	}
+
+    /* would be nicer if we do not have to clone... */
+    sub_clone = ldns_dname_clone_from(sub, 0);
+    parent_clone = ldns_dname_clone_from(parent, 0);
+    ldns_dname2canonical(sub_clone);
+    ldns_dname2canonical(parent_clone);
+
+	sub_lab = ldns_dname_label_count(sub_clone);
+	par_lab = ldns_dname_label_count(parent_clone);
+
+	/* if sub sits above parent, it cannot be a child/sub domain */
+	if (sub_lab < par_lab) {
+		result = false;
+	} else {
+		/* check all labels the from the parent labels, from right to left.
+		 * When they /all/ match we have found a subdomain
+		 */
+		j = sub_lab - 1; /* we count from zero, thank you */
+		for (i = par_lab -1; i >= 0; i--) {
+			tmp_sub = ldns_dname_label(sub_clone, j);
+			tmp_par = ldns_dname_label(parent_clone, i);
+			if (!tmp_sub || !tmp_par) {
+				/* deep free does null check */
+				ldns_rdf_deep_free(tmp_sub);
+				ldns_rdf_deep_free(tmp_par);
+				result = false;
+				break;
+			}
+
+			if (ldns_rdf_compare(tmp_sub, tmp_par) != 0) {
+				/* they are not equal */
+				ldns_rdf_deep_free(tmp_sub);
+				ldns_rdf_deep_free(tmp_par);
+				result = false;
+				break;
+			}
+			ldns_rdf_deep_free(tmp_sub);
+			ldns_rdf_deep_free(tmp_par);
+			j--;
+		}
+	}
+	ldns_rdf_deep_free(sub_clone);
+	ldns_rdf_deep_free(parent_clone);
+	return result;
+}
+
+int
+ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
+{
+	size_t lc1, lc2, lc1f, lc2f;
+	size_t i;
+	int result = 0;
+	uint8_t *lp1, *lp2;
+
+	/* see RFC4034 for this algorithm */
+	/* this algorithm assumes the names are normalized to case */
+
+        /* only when both are not NULL we can say anything about them */
+        if (!dname1 && !dname2) {
+                return 0;
+        }
+        if (!dname1 || !dname2) {
+                return -1;
+        }
+	/* asserts must happen later as we are looking in the
+	 * dname, which could be NULL. But this case is handled
+	 * above
+	 */
+	assert(ldns_rdf_get_type(dname1) == LDNS_RDF_TYPE_DNAME);
+	assert(ldns_rdf_get_type(dname2) == LDNS_RDF_TYPE_DNAME);
+
+	lc1 = ldns_dname_label_count(dname1);
+	lc2 = ldns_dname_label_count(dname2);
+
+	if (lc1 == 0 && lc2 == 0) {
+		return 0;
+	}
+	if (lc1 == 0) {
+		return -1;
+	}
+	if (lc2 == 0) {
+		return 1;
+	}
+	lc1--;
+	lc2--;
+	/* we start at the last label */
+	while (true) {
+		/* find the label first */
+		lc1f = lc1;
+		lp1 = ldns_rdf_data(dname1);
+		while (lc1f > 0) {
+			lp1 += *lp1 + 1;
+			lc1f--;
+		}
+
+		/* and find the other one */
+		lc2f = lc2;
+		lp2 = ldns_rdf_data(dname2);
+		while (lc2f > 0) {
+			lp2 += *lp2 + 1;
+			lc2f--;
+		}
+
+		/* now check the label character for character. */
+		for (i = 1; i < (size_t)(*lp1 + 1); i++) {
+			if (i > *lp2) {
+				/* apparently label 1 is larger */
+				result = 1;
+				goto done;
+			}
+			if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) <
+			    LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
+			    result = -1;
+			    goto done;
+			} else if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) >
+			    LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
+			    result = 1;
+			    goto done;
+			}
+		}
+		if (*lp1 < *lp2) {
+			/* apparently label 2 is larger */
+			result = -1;
+			goto done;
+		}
+		if (lc1 == 0 && lc2 > 0) {
+			result = -1;
+			goto done;
+		} else if (lc1 > 0 && lc2 == 0) {
+			result = 1;
+			goto done;
+		} else if (lc1 == 0 && lc2 == 0) {
+			result = 0;
+			goto done;
+		}
+		lc1--;
+		lc2--;
+	}
+
+	done:
+	return result;
+}
+
+int
+ldns_dname_is_wildcard(const ldns_rdf* dname)
+{
+	return ( ldns_dname_label_count(dname) > 0 &&
+		 ldns_rdf_data(dname)[0] == 1 &&
+		 ldns_rdf_data(dname)[1] == '*');
+}
+
+int
+ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard)
+{
+	ldns_rdf *wc_chopped;
+	int result;
+	/* check whether it really is a wildcard */
+	if (ldns_dname_is_wildcard(wildcard)) {
+		/* ok, so the dname needs to be a subdomain of the wildcard
+		 * without the *
+		 */
+		wc_chopped = ldns_dname_left_chop(wildcard);
+		result = (int) ldns_dname_is_subdomain(dname, wc_chopped);
+		ldns_rdf_deep_free(wc_chopped);
+	} else {
+		result = (ldns_dname_compare(dname, wildcard) == 0);
+	}
+	return result;
+}
+
+/* nsec test: does prev <= middle < next
+ * -1 = yes
+ * 0 = error/can't tell
+ * 1 = no
+ */
+int
+ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle,
+		const ldns_rdf *next)
+{
+	int prev_check, next_check;
+
+	assert(ldns_rdf_get_type(prev) == LDNS_RDF_TYPE_DNAME);
+	assert(ldns_rdf_get_type(middle) == LDNS_RDF_TYPE_DNAME);
+	assert(ldns_rdf_get_type(next) == LDNS_RDF_TYPE_DNAME);
+
+	prev_check = ldns_dname_compare(prev, middle);
+	next_check = ldns_dname_compare(middle, next);
+	/* <= next. This cannot be the case for nsec, because then we would
+	 * have gotten the nsec of next...
+	 */
+	if (next_check == 0) {
+		return 0;
+	}
+
+			/* <= */
+	if ((prev_check == -1 || prev_check == 0) &&
+			/* < */
+			next_check == -1) {
+		return -1;
+	} else {
+		return 1;
+	}
+}
+
+
+bool
+ldns_dname_str_absolute(const char *dname_str)
+{
+        const char* s;
+	if(dname_str && strcmp(dname_str, ".") == 0)
+		return 1;
+        if(!dname_str || strlen(dname_str) < 2)
+                return 0;
+        if(dname_str[strlen(dname_str) - 1] != '.')
+                return 0;
+        if(dname_str[strlen(dname_str) - 2] != '\\')
+                return 1; /* ends in . and no \ before it */
+        /* so we have the case of ends in . and there is \ before it */
+        for(s=dname_str; *s; s++) {
+                if(*s == '\\') {
+                        if(s[1] && s[2] && s[3] /* check length */
+                                && isdigit(s[1]) && isdigit(s[2]) && 
+                                isdigit(s[3]))
+                                s += 3;
+                        else if(!s[1] || isdigit(s[1])) /* escape of nul,0-9 */
+                                return 0; /* parse error */
+                        else s++; /* another character escaped */
+                }
+                else if(!*(s+1) && *s == '.')
+                        return 1; /* trailing dot, unescaped */
+        }
+        return 0;
+}
+
+bool
+ldns_dname_absolute(const ldns_rdf *rdf)
+{
+	char *str = ldns_rdf2str(rdf);
+	if (str) {
+		bool r = ldns_dname_str_absolute(str);
+		LDNS_FREE(str);
+		return r;
+	}
+	return false;
+}
+
+ldns_rdf *
+ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
+{
+	uint8_t labelcnt;
+	uint16_t src_pos;
+	uint16_t len;
+	ldns_rdf *tmpnew;
+	size_t s;
+	uint8_t *data;
+
+	if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_DNAME) {
+		return NULL;
+	}
+
+	labelcnt = 0;
+	src_pos = 0;
+	s = ldns_rdf_size(rdf);
+
+	len = ldns_rdf_data(rdf)[src_pos]; /* label start */
+	while ((len > 0) && src_pos < s) {
+		if (labelcnt == labelpos) {
+			/* found our label */
+			data = LDNS_XMALLOC(uint8_t, len + 2);
+			if (!data) {
+				return NULL;
+			}
+			memcpy(data, ldns_rdf_data(rdf) + src_pos, len + 1);
+			data[len + 2 - 1] = 0;
+
+			tmpnew = ldns_rdf_new( LDNS_RDF_TYPE_DNAME
+					     , len + 2, data);
+			if (!tmpnew) {
+				LDNS_FREE(data);
+				return NULL;
+			}
+			return tmpnew;
+		}
+		src_pos++;
+		src_pos += len;
+		len = ldns_rdf_data(rdf)[src_pos];
+		labelcnt++;
+	}
+	return NULL;
+}
diff --git a/ldns/src/dnssec.c b/ldns/src/dnssec.c
new file mode 100644
index 0000000..a41a9f6
--- /dev/null
+++ b/ldns/src/dnssec.c
@@ -0,0 +1,1869 @@
+/*
+ * dnssec.c
+ *
+ * contains the cryptographic function needed for DNSSEC in ldns
+ * The crypto library used is openssl
+ *
+ * (c) NLnet Labs, 2004-2008
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+#include <ldns/dnssec.h>
+
+#include <strings.h>
+#include <time.h>
+
+#ifdef HAVE_SSL
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/md5.h>
+#endif
+
+ldns_rr *
+ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name,
+                                        const ldns_rr_type type,
+                                        const ldns_rr_list *rrs)
+{
+	size_t i;
+	ldns_rr *candidate;
+
+	if (!name || !rrs) {
+		return NULL;
+	}
+
+	for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
+		candidate = ldns_rr_list_rr(rrs, i);
+		if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_RRSIG) {
+			if (ldns_dname_compare(ldns_rr_owner(candidate),
+			                       name) == 0 &&
+			    ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(candidate))
+			    == type
+			    ) {
+				return candidate;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+ldns_rr *
+ldns_dnssec_get_dnskey_for_rrsig(const ldns_rr *rrsig,
+						   const ldns_rr_list *rrs)
+{
+	size_t i;
+	ldns_rr *candidate;
+
+	if (!rrsig || !rrs) {
+		return NULL;
+	}
+
+	for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
+		candidate = ldns_rr_list_rr(rrs, i);
+		if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_DNSKEY) {
+			if (ldns_dname_compare(ldns_rr_owner(candidate),
+			                       ldns_rr_rrsig_signame(rrsig)) == 0 &&
+			    ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig)) ==
+			    ldns_calc_keytag(candidate)
+			    ) {
+				return candidate;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+ldns_rdf *
+ldns_nsec_get_bitmap(ldns_rr *nsec) {
+	if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
+		return ldns_rr_rdf(nsec, 1);
+	} else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
+		return ldns_rr_rdf(nsec, 5);
+	} else {
+		return NULL;
+	}
+}
+
+/*return the owner name of the closest encloser for name from the list of rrs */
+/* this is NOT the hash, but the original name! */
+ldns_rdf *
+ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
+                                   ATTR_UNUSED(ldns_rr_type qtype),
+                                   ldns_rr_list *nsec3s)
+{
+	/* remember parameters, they must match */
+	uint8_t algorithm;
+	uint32_t iterations;
+	uint8_t salt_length;
+	uint8_t *salt;
+
+	ldns_rdf *sname, *hashed_sname, *tmp;
+	bool flag;
+
+	bool exact_match_found;
+	bool in_range_found;
+
+	ldns_status status;
+	ldns_rdf *zone_name;
+
+	size_t nsec_i;
+	ldns_rr *nsec;
+	ldns_rdf *result = NULL;
+
+	if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) {
+		return NULL;
+	}
+
+	nsec = ldns_rr_list_rr(nsec3s, 0);
+	algorithm = ldns_nsec3_algorithm(nsec);
+	salt_length = ldns_nsec3_salt_length(nsec);
+	salt = ldns_nsec3_salt_data(nsec);
+	iterations = ldns_nsec3_iterations(nsec);
+
+	sname = ldns_rdf_clone(qname);
+
+	flag = false;
+
+	zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec));
+
+	/* algorithm from nsec3-07 8.3 */
+	while (ldns_dname_label_count(sname) > 0) {
+		exact_match_found = false;
+		in_range_found = false;
+
+		hashed_sname = ldns_nsec3_hash_name(sname,
+									 algorithm,
+									 iterations,
+									 salt_length,
+									 salt);
+
+		status = ldns_dname_cat(hashed_sname, zone_name);
+                if(status != LDNS_STATUS_OK) {
+	                LDNS_FREE(salt);
+	                ldns_rdf_deep_free(zone_name);
+	                ldns_rdf_deep_free(sname);
+                        return NULL;
+                }
+
+		for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) {
+			nsec = ldns_rr_list_rr(nsec3s, nsec_i);
+
+			/* check values of iterations etc! */
+
+			/* exact match? */
+			if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) {
+			 	exact_match_found = true;
+			} else if (ldns_nsec_covers_name(nsec, hashed_sname)) {
+				in_range_found = true;
+			}
+
+		}
+		if (!exact_match_found && in_range_found) {
+			flag = true;
+		} else if (exact_match_found && flag) {
+			result = ldns_rdf_clone(sname);
+			/* RFC 5155: 8.3. 2.** "The proof is complete" */
+			ldns_rdf_deep_free(hashed_sname);
+			goto done;
+		} else if (exact_match_found && !flag) {
+			/* error! */
+			ldns_rdf_deep_free(hashed_sname);
+			goto done;
+		} else {
+			flag = false;
+		}
+
+		ldns_rdf_deep_free(hashed_sname);
+		tmp = sname;
+		sname = ldns_dname_left_chop(sname);
+		ldns_rdf_deep_free(tmp);
+	}
+
+	done:
+	LDNS_FREE(salt);
+	ldns_rdf_deep_free(zone_name);
+	ldns_rdf_deep_free(sname);
+
+	return result;
+}
+
+bool
+ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt)
+{
+	size_t i;
+	for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
+		if (ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_answer(pkt), i)) ==
+		    LDNS_RR_TYPE_RRSIG) {
+			return true;
+		}
+	}
+	for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
+		if (ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_authority(pkt), i)) ==
+		    LDNS_RR_TYPE_RRSIG) {
+			return true;
+		}
+	}
+	return false;
+}
+
+ldns_rr_list *
+ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt,
+									ldns_rdf *name,
+									ldns_rr_type type)
+{
+	uint16_t t_netorder;
+	ldns_rr_list *sigs;
+	ldns_rr_list *sigs_covered;
+	ldns_rdf *rdf_t;
+	
+	sigs = ldns_pkt_rr_list_by_name_and_type(pkt,
+									 name,
+									 LDNS_RR_TYPE_RRSIG,
+									 LDNS_SECTION_ANY_NOQUESTION
+									 );
+
+	t_netorder = htons(type); /* rdf are in network order! */
+	rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, LDNS_RDF_SIZE_WORD, &t_netorder);
+	sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
+	
+	ldns_rdf_free(rdf_t);
+	ldns_rr_list_deep_free(sigs);
+
+	return sigs_covered;
+
+}
+
+ldns_rr_list *
+ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type)
+{
+	uint16_t t_netorder;
+	ldns_rr_list *sigs;
+	ldns_rr_list *sigs_covered;
+	ldns_rdf *rdf_t;
+
+	sigs = ldns_pkt_rr_list_by_type(pkt,
+	                                LDNS_RR_TYPE_RRSIG,
+	                                LDNS_SECTION_ANY_NOQUESTION
+							  );
+
+	t_netorder = htons(type); /* rdf are in network order! */
+	rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE,
+					 2,
+					 &t_netorder);
+	sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
+
+	ldns_rdf_free(rdf_t);
+	ldns_rr_list_deep_free(sigs);
+
+	return sigs_covered;
+
+}
+
+/* used only on the public key RR */
+uint16_t
+ldns_calc_keytag(const ldns_rr *key)
+{
+	uint16_t ac16;
+	ldns_buffer *keybuf;
+	size_t keysize;
+
+	if (!key) {
+		return 0;
+	}
+
+	if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY &&
+	    ldns_rr_get_type(key) != LDNS_RR_TYPE_KEY
+	    ) {
+		return 0;
+	}
+
+	/* rdata to buf - only put the rdata in a buffer */
+	keybuf = ldns_buffer_new(LDNS_MIN_BUFLEN); /* grows */
+	if (!keybuf) {
+		return 0;
+	}
+	(void)ldns_rr_rdata2buffer_wire(keybuf, key);
+	/* the current pos in the buffer is the keysize */
+	keysize= ldns_buffer_position(keybuf);
+
+	ac16 = ldns_calc_keytag_raw(ldns_buffer_begin(keybuf), keysize);
+	ldns_buffer_free(keybuf);
+	return ac16;
+}
+
+uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize)
+{
+	unsigned int i;
+	uint32_t ac32;
+	uint16_t ac16;
+
+	if(keysize < 4) {
+		return 0;
+	}
+	/* look at the algorithm field, copied from 2535bis */
+	if (key[3] == LDNS_RSAMD5) {
+		ac16 = 0;
+		if (keysize > 4) {
+			memmove(&ac16, key + keysize - 3, 2);
+		}
+		ac16 = ntohs(ac16);
+		return (uint16_t) ac16;
+	} else {
+		ac32 = 0;
+		for (i = 0; (size_t)i < keysize; ++i) {
+			ac32 += (i & 1) ? key[i] : key[i] << 8;
+		}
+		ac32 += (ac32 >> 16) & 0xFFFF;
+		return (uint16_t) (ac32 & 0xFFFF);
+	}
+}
+
+#ifdef HAVE_SSL
+DSA *
+ldns_key_buf2dsa(ldns_buffer *key)
+{
+	return ldns_key_buf2dsa_raw((unsigned char*)ldns_buffer_begin(key),
+						   ldns_buffer_position(key));
+}
+
+DSA *
+ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
+{
+	uint8_t T;
+	uint16_t length;
+	uint16_t offset;
+	DSA *dsa;
+	BIGNUM *Q; BIGNUM *P;
+	BIGNUM *G; BIGNUM *Y;
+
+	if(len == 0)
+		return NULL;
+	T = (uint8_t)key[0];
+	length = (64 + T * 8);
+	offset = 1;
+
+	if (T > 8) {
+		return NULL;
+	}
+	if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
+		return NULL;
+
+	Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
+	offset += SHA_DIGEST_LENGTH;
+
+	P = BN_bin2bn(key+offset, (int)length, NULL);
+	offset += length;
+
+	G = BN_bin2bn(key+offset, (int)length, NULL);
+	offset += length;
+
+	Y = BN_bin2bn(key+offset, (int)length, NULL);
+	offset += length;
+
+	/* create the key and set its properties */
+	if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
+		BN_free(Q);
+		BN_free(P);
+		BN_free(G);
+		BN_free(Y);
+		return NULL;
+	}
+#ifndef S_SPLINT_S
+	dsa->p = P;
+	dsa->q = Q;
+	dsa->g = G;
+	dsa->pub_key = Y;
+#endif /* splint */
+
+	return dsa;
+}
+
+RSA *
+ldns_key_buf2rsa(ldns_buffer *key)
+{
+	return ldns_key_buf2rsa_raw((unsigned char*)ldns_buffer_begin(key),
+						   ldns_buffer_position(key));
+}
+
+RSA *
+ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
+{
+	uint16_t offset;
+	uint16_t exp;
+	uint16_t int16;
+	RSA *rsa;
+	BIGNUM *modulus;
+	BIGNUM *exponent;
+
+	if (len == 0)
+		return NULL;
+	if (key[0] == 0) {
+		if(len < 3)
+			return NULL;
+		/* need some smart comment here XXX*/
+		/* the exponent is too large so it's places
+		 * futher...???? */
+		memmove(&int16, key+1, 2);
+		exp = ntohs(int16);
+		offset = 3;
+	} else {
+		exp = key[0];
+		offset = 1;
+	}
+
+	/* key length at least one */
+	if(len < (size_t)offset + exp + 1)
+		return NULL;
+
+	/* Exponent */
+	exponent = BN_new();
+	if(!exponent) return NULL;
+	(void) BN_bin2bn(key+offset, (int)exp, exponent);
+	offset += exp;
+
+	/* Modulus */
+	modulus = BN_new();
+	if(!modulus) {
+		BN_free(exponent);
+		return NULL;
+	}
+	/* length of the buffer must match the key length! */
+	(void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
+
+	rsa = RSA_new();
+	if(!rsa) {
+		BN_free(exponent);
+		BN_free(modulus);
+		return NULL;
+	}
+#ifndef S_SPLINT_S
+	rsa->n = modulus;
+	rsa->e = exponent;
+#endif /* splint */
+
+	return rsa;
+}
+
+int
+ldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
+	const EVP_MD* md)
+{
+	EVP_MD_CTX* ctx;
+	ctx = EVP_MD_CTX_create();
+	if(!ctx)
+		return false;
+	if(!EVP_DigestInit_ex(ctx, md, NULL) ||
+		!EVP_DigestUpdate(ctx, data, len) ||
+		!EVP_DigestFinal_ex(ctx, dest, NULL)) {
+		EVP_MD_CTX_destroy(ctx);
+		return false;
+	}
+	EVP_MD_CTX_destroy(ctx);
+	return true;
+}
+#endif /* HAVE_SSL */
+
+ldns_rr *
+ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
+{
+	ldns_rdf *tmp;
+	ldns_rr *ds;
+	uint16_t keytag;
+	uint8_t  sha1hash;
+	uint8_t *digest;
+	ldns_buffer *data_buf;
+#ifdef USE_GOST
+	const EVP_MD* md = NULL;
+#endif
+
+	if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY) {
+		return NULL;
+	}
+
+	ds = ldns_rr_new();
+	if (!ds) {
+		return NULL;
+	}
+	ldns_rr_set_type(ds, LDNS_RR_TYPE_DS);
+	ldns_rr_set_owner(ds, ldns_rdf_clone(
+								  ldns_rr_owner(key)));
+	ldns_rr_set_ttl(ds, ldns_rr_ttl(key));
+	ldns_rr_set_class(ds, ldns_rr_get_class(key));
+
+	switch(h) {
+	default:
+	case LDNS_SHA1:
+		digest = LDNS_XMALLOC(uint8_t, LDNS_SHA1_DIGEST_LENGTH);
+		if (!digest) {
+			ldns_rr_free(ds);
+			return NULL;
+		}
+		break;
+	case LDNS_SHA256:
+		digest = LDNS_XMALLOC(uint8_t, LDNS_SHA256_DIGEST_LENGTH);
+		if (!digest) {
+			ldns_rr_free(ds);
+			return NULL;
+		}
+		break;
+	case LDNS_HASH_GOST:
+#ifdef USE_GOST
+		(void)ldns_key_EVP_load_gost_id();
+		md = EVP_get_digestbyname("md_gost94");
+		if(!md) {
+			ldns_rr_free(ds);
+			return NULL;
+		}
+		digest = LDNS_XMALLOC(uint8_t, EVP_MD_size(md));
+		if (!digest) {
+			ldns_rr_free(ds);
+			return NULL;
+		}
+                break;
+#else
+		/* not implemented */
+		ldns_rr_free(ds);
+		return NULL;
+#endif
+	case LDNS_SHA384:
+#ifdef USE_ECDSA
+		digest = LDNS_XMALLOC(uint8_t, SHA384_DIGEST_LENGTH);
+		if (!digest) {
+			ldns_rr_free(ds);
+			return NULL;
+		}
+                break;
+#else
+		/* not implemented */
+		ldns_rr_free(ds);
+		return NULL;
+#endif
+	}
+
+	data_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	if (!data_buf) {
+		LDNS_FREE(digest);
+		ldns_rr_free(ds);
+		return NULL;
+	}
+
+	/* keytag */
+	keytag = htons(ldns_calc_keytag((ldns_rr*)key));
+	tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16,
+						   sizeof(uint16_t),
+						   &keytag);
+	ldns_rr_push_rdf(ds, tmp);
+
+	/* copy the algorithm field */
+	if ((tmp = ldns_rr_rdf(key, 2)) == NULL) {
+		LDNS_FREE(digest);
+		ldns_buffer_free(data_buf);
+		ldns_rr_free(ds);
+		return NULL;
+	} else {
+		ldns_rr_push_rdf(ds, ldns_rdf_clone( tmp )); 
+	}
+
+	/* digest hash type */
+	sha1hash = (uint8_t)h;
+	tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8,
+						   sizeof(uint8_t),
+						   &sha1hash);
+	ldns_rr_push_rdf(ds, tmp);
+
+	/* digest */
+	/* owner name */
+	tmp = ldns_rdf_clone(ldns_rr_owner(key));
+	ldns_dname2canonical(tmp);
+	if (ldns_rdf2buffer_wire(data_buf, tmp) != LDNS_STATUS_OK) {
+		LDNS_FREE(digest);
+		ldns_buffer_free(data_buf);
+		ldns_rr_free(ds);
+		ldns_rdf_deep_free(tmp);
+		return NULL;
+	}
+	ldns_rdf_deep_free(tmp);
+
+	/* all the rdata's */
+	if (ldns_rr_rdata2buffer_wire(data_buf,
+							(ldns_rr*)key) != LDNS_STATUS_OK) {
+		LDNS_FREE(digest);
+		ldns_buffer_free(data_buf);
+		ldns_rr_free(ds);
+		return NULL;
+	}
+	switch(h) {
+	case LDNS_SHA1:
+		(void) ldns_sha1((unsigned char *) ldns_buffer_begin(data_buf),
+		                 (unsigned int) ldns_buffer_position(data_buf),
+		                 (unsigned char *) digest);
+
+		tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
+		                            LDNS_SHA1_DIGEST_LENGTH,
+		                            digest);
+		ldns_rr_push_rdf(ds, tmp);
+
+		break;
+	case LDNS_SHA256:
+		(void) ldns_sha256((unsigned char *) ldns_buffer_begin(data_buf),
+		                   (unsigned int) ldns_buffer_position(data_buf),
+		                   (unsigned char *) digest);
+		tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
+		                            LDNS_SHA256_DIGEST_LENGTH,
+		                            digest);
+		ldns_rr_push_rdf(ds, tmp);
+		break;
+	case LDNS_HASH_GOST:
+#ifdef USE_GOST
+		if(!ldns_digest_evp((unsigned char *) ldns_buffer_begin(data_buf),
+				(unsigned int) ldns_buffer_position(data_buf),
+				(unsigned char *) digest, md)) {
+			LDNS_FREE(digest);
+			ldns_buffer_free(data_buf);
+			ldns_rr_free(ds);
+			return NULL;
+		}
+		tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
+		                            (size_t)EVP_MD_size(md),
+		                            digest);
+		ldns_rr_push_rdf(ds, tmp);
+#endif
+		break;
+	case LDNS_SHA384:
+#ifdef USE_ECDSA
+		(void) SHA384((unsigned char *) ldns_buffer_begin(data_buf),
+		                 (unsigned int) ldns_buffer_position(data_buf),
+		                 (unsigned char *) digest);
+		tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
+		                            SHA384_DIGEST_LENGTH,
+		                            digest);
+		ldns_rr_push_rdf(ds, tmp);
+#endif
+		break;
+	}
+
+	LDNS_FREE(digest);
+	ldns_buffer_free(data_buf);
+	return ds;
+}
+
+/* From RFC3845:
+ *
+ * 2.1.2.  The List of Type Bit Map(s) Field
+ * 
+ *    The RR type space is split into 256 window blocks, each representing
+ *    the low-order 8 bits of the 16-bit RR type space.  Each block that
+ *    has at least one active RR type is encoded using a single octet
+ *    window number (from 0 to 255), a single octet bitmap length (from 1
+ *    to 32) indicating the number of octets used for the window block's
+ *    bitmap, and up to 32 octets (256 bits) of bitmap.
+ * 
+ *    Window blocks are present in the NSEC RR RDATA in increasing
+ *    numerical order.
+ * 
+ *    "|" denotes concatenation
+ * 
+ *    Type Bit Map(s) Field = ( Window Block # | Bitmap Length | Bitmap ) +
+ * 
+ *    <cut>
+ * 
+ *    Blocks with no types present MUST NOT be included.  Trailing zero
+ *    octets in the bitmap MUST be omitted.  The length of each block's
+ *    bitmap is determined by the type code with the largest numerical
+ *    value within that block, among the set of RR types present at the
+ *    NSEC RR's owner name.  Trailing zero octets not specified MUST be
+ *    interpreted as zero octets.
+ */
+ldns_rdf *
+ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
+                               size_t size,
+                               ldns_rr_type nsec_type)
+{
+	uint8_t  window;		/*  most significant octet of type */
+	uint8_t  subtype;		/* least significant octet of type */
+	uint16_t windows[256]		/* Max subtype per window */
+#ifndef S_SPLINT_S
+	                      = { 0 }	/* Initialize ALL elements with 0 */
+#endif
+	                             ;
+	ldns_rr_type* d;	/* used to traverse rr_type_list*/
+	size_t i;		/* used to traverse windows array */
+
+	size_t sz;			/* size needed for type bitmap rdf */
+	uint8_t* data = NULL;		/* rdf data */
+	uint8_t* dptr;			/* used to itraverse rdf data */
+	ldns_rdf* rdf;			/* bitmap rdf to return */
+
+	if (nsec_type != LDNS_RR_TYPE_NSEC &&
+	    nsec_type != LDNS_RR_TYPE_NSEC3) {
+		return NULL;
+	}
+
+	/* Which other windows need to be in the bitmap rdf?
+	 */
+	for (d = rr_type_list; d < rr_type_list + size; d++) {
+		window  = *d >> 8;
+		subtype = *d & 0xff;
+		if (windows[window] < subtype) {
+			windows[window] = subtype;
+		}
+	}
+
+	/* How much space do we need in the rdf for those windows?
+	 */
+	sz = 0;
+	for (i = 0; i < 256; i++) {
+		if (windows[i]) {
+			sz += windows[i] / 8 + 3;
+		}
+	}
+	if (sz > 0) {
+		/* Format rdf data according RFC3845 Section 2.1.2 (see above)
+		 */
+		dptr = data = LDNS_CALLOC(uint8_t, sz);
+		if (!data) {
+			return NULL;
+		}
+		for (i = 0; i < 256; i++) {
+			if (windows[i]) {
+				*dptr++ = (uint8_t)i;
+				*dptr++ = (uint8_t)(windows[i] / 8 + 1);
+
+				/* Now let windows[i] index the bitmap
+				 * within data
+				 */
+				windows[i] = (uint16_t)(dptr - data);
+
+				dptr += dptr[-1];
+			}
+		}
+	}
+
+	/* Set the bits?
+	 */
+	for (d = rr_type_list; d < rr_type_list + size; d++) {
+		subtype = *d & 0xff;
+		data[windows[*d >> 8] + subtype/8] |= (0x80 >> (subtype % 8));
+	}
+
+	/* Allocate and return rdf structure for the data
+	 */
+	rdf = ldns_rdf_new(LDNS_RDF_TYPE_BITMAP, sz, data);
+	if (!rdf) {
+		LDNS_FREE(data);
+		return NULL;
+	}
+	return rdf;
+}
+
+int
+ldns_dnssec_rrsets_contains_type(ldns_dnssec_rrsets *rrsets,
+                                 ldns_rr_type type)
+{
+	ldns_dnssec_rrsets *cur_rrset = rrsets;
+	while (cur_rrset) {
+		if (cur_rrset->type == type) {
+			return 1;
+		}
+		cur_rrset = cur_rrset->next;
+	}
+	return 0;
+}
+
+ldns_rr *
+ldns_dnssec_create_nsec(ldns_dnssec_name *from,
+                        ldns_dnssec_name *to,
+                        ldns_rr_type nsec_type)
+{
+	ldns_rr *nsec_rr;
+	ldns_rr_type types[65536];
+	size_t type_count = 0;
+	ldns_dnssec_rrsets *cur_rrsets;
+	int on_delegation_point;
+
+	if (!from || !to || (nsec_type != LDNS_RR_TYPE_NSEC)) {
+		return NULL;
+	}
+
+	nsec_rr = ldns_rr_new();
+	ldns_rr_set_type(nsec_rr, nsec_type);
+	ldns_rr_set_owner(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(from)));
+	ldns_rr_push_rdf(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(to)));
+
+	on_delegation_point = ldns_dnssec_rrsets_contains_type(
+			from->rrsets, LDNS_RR_TYPE_NS)
+		&& !ldns_dnssec_rrsets_contains_type(
+			from->rrsets, LDNS_RR_TYPE_SOA);
+
+	cur_rrsets = from->rrsets;
+	while (cur_rrsets) {
+		/* Do not include non-authoritative rrsets on the delegation point
+		 * in the type bitmap */
+		if ((on_delegation_point && (
+				cur_rrsets->type == LDNS_RR_TYPE_NS 
+			     || cur_rrsets->type == LDNS_RR_TYPE_DS))
+			|| (!on_delegation_point &&
+				cur_rrsets->type != LDNS_RR_TYPE_RRSIG
+			     && cur_rrsets->type != LDNS_RR_TYPE_NSEC)) {
+
+			types[type_count] = cur_rrsets->type;
+			type_count++;
+		}
+		cur_rrsets = cur_rrsets->next;
+
+	}
+	types[type_count] = LDNS_RR_TYPE_RRSIG;
+	type_count++;
+	types[type_count] = LDNS_RR_TYPE_NSEC;
+	type_count++;
+
+	ldns_rr_push_rdf(nsec_rr, ldns_dnssec_create_nsec_bitmap(types,
+	                               type_count,
+	                               nsec_type));
+
+	return nsec_rr;
+}
+
+ldns_rr *
+ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
+					ldns_dnssec_name *to,
+					ldns_rdf *zone_name,
+					uint8_t algorithm,
+					uint8_t flags,
+					uint16_t iterations,
+					uint8_t salt_length,
+					uint8_t *salt)
+{
+	ldns_rr *nsec_rr;
+	ldns_rr_type types[65536];
+	size_t type_count = 0;
+	ldns_dnssec_rrsets *cur_rrsets;
+	ldns_status status;
+	int on_delegation_point;
+
+	if (!from) {
+		return NULL;
+	}
+
+	nsec_rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3);
+	ldns_rr_set_owner(nsec_rr,
+	                  ldns_nsec3_hash_name(ldns_dnssec_name_name(from),
+	                  algorithm,
+	                  iterations,
+	                  salt_length,
+	                  salt));
+	status = ldns_dname_cat(ldns_rr_owner(nsec_rr), zone_name);
+        if(status != LDNS_STATUS_OK) {
+                ldns_rr_free(nsec_rr);
+                return NULL;
+        }
+	ldns_nsec3_add_param_rdfs(nsec_rr,
+	                          algorithm,
+	                          flags,
+	                          iterations,
+	                          salt_length,
+	                          salt);
+
+	on_delegation_point = ldns_dnssec_rrsets_contains_type(
+			from->rrsets, LDNS_RR_TYPE_NS)
+		&& !ldns_dnssec_rrsets_contains_type(
+			from->rrsets, LDNS_RR_TYPE_SOA);
+	cur_rrsets = from->rrsets;
+	while (cur_rrsets) {
+		/* Do not include non-authoritative rrsets on the delegation point
+		 * in the type bitmap. Potentionally not skipping insecure
+		 * delegation should have been done earlier, in function
+		 * ldns_dnssec_zone_create_nsec3s, or even earlier in:
+		 * ldns_dnssec_zone_sign_nsec3_flg .
+		 */
+		if ((on_delegation_point && (
+				cur_rrsets->type == LDNS_RR_TYPE_NS
+			     || cur_rrsets->type == LDNS_RR_TYPE_DS))
+			|| (!on_delegation_point &&
+				cur_rrsets->type != LDNS_RR_TYPE_RRSIG)) {
+
+			types[type_count] = cur_rrsets->type;
+			type_count++;
+		}
+		cur_rrsets = cur_rrsets->next;
+	}
+	/* always add rrsig type if this is not an unsigned
+	 * delegation
+	 */
+	if (type_count > 0 &&
+	    !(type_count == 1 && types[0] == LDNS_RR_TYPE_NS)) {
+		types[type_count] = LDNS_RR_TYPE_RRSIG;
+		type_count++;
+	}
+
+	/* leave next rdata empty if they weren't precomputed yet */
+	if (to && to->hashed_name) {
+		(void) ldns_rr_set_rdf(nsec_rr,
+		                       ldns_rdf_clone(to->hashed_name),
+		                       4);
+	} else {
+		(void) ldns_rr_set_rdf(nsec_rr, NULL, 4);
+	}
+
+	ldns_rr_push_rdf(nsec_rr,
+	                 ldns_dnssec_create_nsec_bitmap(types,
+	                 type_count,
+	                 LDNS_RR_TYPE_NSEC3));
+
+	return nsec_rr;
+}
+
+ldns_rr *
+ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs)
+{
+	/* we do not do any check here - garbage in, garbage out */
+
+	/* the the start and end names - get the type from the
+	 * before rrlist */
+
+	/* inefficient, just give it a name, a next name, and a list of rrs */
+	/* we make 1 big uberbitmap first, then windows */
+	/* todo: make something more efficient :) */
+	uint16_t i;
+	ldns_rr *i_rr;
+	uint16_t i_type;
+
+	ldns_rr *nsec = NULL;
+	ldns_rr_type i_type_list[65536];
+	size_t type_count = 0;
+
+	nsec = ldns_rr_new();
+	ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC);
+	ldns_rr_set_owner(nsec, ldns_rdf_clone(cur_owner));
+	ldns_rr_push_rdf(nsec, ldns_rdf_clone(next_owner));
+
+	for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
+		i_rr = ldns_rr_list_rr(rrs, i);
+		if (ldns_rdf_compare(cur_owner,
+						 ldns_rr_owner(i_rr)) == 0) {
+			i_type = ldns_rr_get_type(i_rr);
+			if (i_type != LDNS_RR_TYPE_RRSIG && i_type != LDNS_RR_TYPE_NSEC) {
+				if (type_count == 0 || i_type_list[type_count-1] != i_type) {
+					i_type_list[type_count] = i_type;
+					type_count++;
+				}
+			}
+		}
+	}
+
+	i_type_list[type_count] = LDNS_RR_TYPE_RRSIG;
+	type_count++;
+	i_type_list[type_count] = LDNS_RR_TYPE_NSEC;
+	type_count++;
+
+	ldns_rr_push_rdf(nsec,
+				  ldns_dnssec_create_nsec_bitmap(i_type_list,
+						type_count, LDNS_RR_TYPE_NSEC));
+
+	return nsec;
+}
+
+ldns_rdf *
+ldns_nsec3_hash_name(ldns_rdf *name,
+				 uint8_t algorithm,
+				 uint16_t iterations,
+				 uint8_t salt_length,
+				 uint8_t *salt)
+{
+	size_t hashed_owner_str_len;
+	ldns_rdf *cann;
+	ldns_rdf *hashed_owner;
+	unsigned char *hashed_owner_str;
+	char *hashed_owner_b32;
+	size_t hashed_owner_b32_len;
+	uint32_t cur_it;
+	/* define to contain the largest possible hash, which is
+	 * sha1 at the moment */
+	unsigned char hash[LDNS_SHA1_DIGEST_LENGTH];
+	ldns_status status;
+
+	/* TODO: mnemonic list for hash algs SHA-1, default to 1 now (sha1) */
+	if (algorithm != LDNS_SHA1) {
+		return NULL;
+	}
+
+	/* prepare the owner name according to the draft section bla */
+	cann = ldns_rdf_clone(name);
+	if(!cann) {
+#ifdef STDERR_MSGS
+		fprintf(stderr, "Memory error\n");
+#endif
+		return NULL;
+	}
+	ldns_dname2canonical(cann);
+
+	hashed_owner_str_len = salt_length + ldns_rdf_size(cann);
+	hashed_owner_str = LDNS_XMALLOC(unsigned char, hashed_owner_str_len);
+        if(!hashed_owner_str) {
+	        ldns_rdf_deep_free(cann);
+                return NULL;
+        }
+	memcpy(hashed_owner_str, ldns_rdf_data(cann), ldns_rdf_size(cann));
+	memcpy(hashed_owner_str + ldns_rdf_size(cann), salt, salt_length);
+	ldns_rdf_deep_free(cann);
+
+	for (cur_it = iterations + 1; cur_it > 0; cur_it--) {
+		(void) ldns_sha1((unsigned char *) hashed_owner_str,
+		                 (unsigned int) hashed_owner_str_len, hash);
+
+		LDNS_FREE(hashed_owner_str);
+		hashed_owner_str_len = salt_length + LDNS_SHA1_DIGEST_LENGTH;
+		hashed_owner_str = LDNS_XMALLOC(unsigned char, hashed_owner_str_len);
+		if (!hashed_owner_str) {
+			return NULL;
+		}
+		memcpy(hashed_owner_str, hash, LDNS_SHA1_DIGEST_LENGTH);
+		memcpy(hashed_owner_str + LDNS_SHA1_DIGEST_LENGTH, salt, salt_length);
+		hashed_owner_str_len = LDNS_SHA1_DIGEST_LENGTH + salt_length;
+	}
+
+	LDNS_FREE(hashed_owner_str);
+	hashed_owner_str = hash;
+	hashed_owner_str_len = LDNS_SHA1_DIGEST_LENGTH;
+
+	hashed_owner_b32 = LDNS_XMALLOC(char,
+                  ldns_b32_ntop_calculate_size(hashed_owner_str_len) + 1);
+        if(!hashed_owner_b32) {
+                return NULL;
+        }
+        hashed_owner_b32_len = (size_t) ldns_b32_ntop_extended_hex(
+                (uint8_t *) hashed_owner_str,
+                hashed_owner_str_len,
+                hashed_owner_b32,
+                ldns_b32_ntop_calculate_size(hashed_owner_str_len)+1);
+	if (hashed_owner_b32_len < 1) {
+#ifdef STDERR_MSGS
+		fprintf(stderr, "Error in base32 extended hex encoding ");
+		fprintf(stderr, "of hashed owner name (name: ");
+		ldns_rdf_print(stderr, name);
+		fprintf(stderr, ", return code: %u)\n",
+		        (unsigned int) hashed_owner_b32_len);
+#endif
+		LDNS_FREE(hashed_owner_b32);
+		return NULL;
+	}
+	hashed_owner_b32[hashed_owner_b32_len] = '\0';
+
+	status = ldns_str2rdf_dname(&hashed_owner, hashed_owner_b32);
+	if (status != LDNS_STATUS_OK) {
+#ifdef STDERR_MSGS
+		fprintf(stderr, "Error creating rdf from %s\n", hashed_owner_b32);
+#endif
+		LDNS_FREE(hashed_owner_b32);
+		return NULL;
+	}
+
+	LDNS_FREE(hashed_owner_b32);
+	return hashed_owner;
+}
+
+void
+ldns_nsec3_add_param_rdfs(ldns_rr *rr,
+					 uint8_t algorithm,
+					 uint8_t flags,
+					 uint16_t iterations,
+					 uint8_t salt_length,
+					 uint8_t *salt)
+{
+	ldns_rdf *salt_rdf = NULL;
+	uint8_t *salt_data = NULL;
+	ldns_rdf *old;
+
+	old = ldns_rr_set_rdf(rr,
+	                      ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8,
+	                                            1, (void*)&algorithm),
+	                      0);
+	if (old) ldns_rdf_deep_free(old);
+
+	old = ldns_rr_set_rdf(rr,
+	                      ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8,
+	                                            1, (void*)&flags),
+	                      1);
+	if (old) ldns_rdf_deep_free(old);
+
+	old = ldns_rr_set_rdf(rr,
+                          ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
+                                                iterations),
+	                      2);
+	if (old) ldns_rdf_deep_free(old);
+
+	salt_data = LDNS_XMALLOC(uint8_t, salt_length + 1);
+        if(!salt_data) {
+                /* no way to return error */
+                return;
+        }
+	salt_data[0] = salt_length;
+	memcpy(salt_data + 1, salt, salt_length);
+	salt_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT,
+							   salt_length + 1,
+							   salt_data);
+        if(!salt_rdf) {
+                LDNS_FREE(salt_data);
+                /* no way to return error */
+                return;
+        }
+
+	old = ldns_rr_set_rdf(rr, salt_rdf, 3);
+	if (old) ldns_rdf_deep_free(old);
+	LDNS_FREE(salt_data);
+}
+
+static int
+rr_list_delegation_only(ldns_rdf *origin, ldns_rr_list *rr_list)
+{
+	size_t i;
+	ldns_rr *cur_rr;
+	if (!origin || !rr_list) return 0;
+	for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
+		cur_rr = ldns_rr_list_rr(rr_list, i);
+		if (ldns_dname_compare(ldns_rr_owner(cur_rr), origin) == 0) {
+			return 0;
+		}
+		if (ldns_rr_get_type(cur_rr) != LDNS_RR_TYPE_NS) {
+			return 0;
+		}
+	}
+	return 1;
+}
+
+/* this will NOT return the NSEC3  completed, you will have to run the
+   finalize function on the rrlist later! */
+ldns_rr *
+ldns_create_nsec3(ldns_rdf *cur_owner,
+                  ldns_rdf *cur_zone,
+                  ldns_rr_list *rrs,
+                  uint8_t algorithm,
+                  uint8_t flags,
+                  uint16_t iterations,
+                  uint8_t salt_length,
+                  uint8_t *salt,
+                  bool emptynonterminal)
+{
+	size_t i;
+	ldns_rr *i_rr;
+	uint16_t i_type;
+
+	ldns_rr *nsec = NULL;
+	ldns_rdf *hashed_owner = NULL;
+
+	ldns_status status;
+
+    ldns_rr_type i_type_list[1024];
+	size_t type_count = 0;
+
+	hashed_owner = ldns_nsec3_hash_name(cur_owner,
+								 algorithm,
+								 iterations,
+								 salt_length,
+								 salt);
+	status = ldns_dname_cat(hashed_owner, cur_zone);
+        if(status != LDNS_STATUS_OK) {
+		ldns_rdf_deep_free(hashed_owner);
+                return NULL;
+	}
+	nsec = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3);
+        if(!nsec) {
+		ldns_rdf_deep_free(hashed_owner);
+                return NULL;
+	}
+	ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC3);
+	ldns_rr_set_owner(nsec, hashed_owner);
+
+	ldns_nsec3_add_param_rdfs(nsec,
+						 algorithm,
+						 flags,
+						 iterations,
+						 salt_length,
+						 salt);
+	(void) ldns_rr_set_rdf(nsec, NULL, 4);
+
+
+	for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
+		i_rr = ldns_rr_list_rr(rrs, i);
+		if (ldns_rdf_compare(cur_owner,
+						 ldns_rr_owner(i_rr)) == 0) {
+			i_type = ldns_rr_get_type(i_rr);
+			if (type_count == 0 || i_type_list[type_count-1] != i_type) {
+				i_type_list[type_count] = i_type;
+				type_count++;
+			}
+		}
+	}
+
+	/* add RRSIG anyway, but only if this is not an ENT or
+	 * an unsigned delegation */
+	if (!emptynonterminal && !rr_list_delegation_only(cur_zone, rrs)) {
+		i_type_list[type_count] = LDNS_RR_TYPE_RRSIG;
+		type_count++;
+	}
+
+	/* and SOA if owner == zone */
+	if (ldns_dname_compare(cur_zone, cur_owner) == 0) {
+		i_type_list[type_count] = LDNS_RR_TYPE_SOA;
+		type_count++;
+	}
+
+	ldns_rr_push_rdf(nsec,
+				  ldns_dnssec_create_nsec_bitmap(i_type_list,
+						type_count, LDNS_RR_TYPE_NSEC3));
+
+	return nsec;
+}
+
+uint8_t
+ldns_nsec3_algorithm(const ldns_rr *nsec3_rr)
+{
+	if (nsec3_rr && 
+	      (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
+	       ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
+	    && (ldns_rr_rdf(nsec3_rr, 0) != NULL)
+	    && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 0)) > 0) {
+		return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 0));
+	}
+	return 0;
+}
+
+uint8_t
+ldns_nsec3_flags(const ldns_rr *nsec3_rr)
+{
+	if (nsec3_rr && 
+	      (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
+	       ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
+	    && (ldns_rr_rdf(nsec3_rr, 1) != NULL)
+	    && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 1)) > 0) {
+		return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 1));
+	}
+	return 0;
+}
+
+bool
+ldns_nsec3_optout(const ldns_rr *nsec3_rr)
+{
+	return (ldns_nsec3_flags(nsec3_rr) & LDNS_NSEC3_VARS_OPTOUT_MASK);
+}
+
+uint16_t
+ldns_nsec3_iterations(const ldns_rr *nsec3_rr)
+{
+	if (nsec3_rr &&
+	      (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
+	       ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
+	    && (ldns_rr_rdf(nsec3_rr, 2) != NULL)
+	    && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 2)) > 0) {
+		return ldns_rdf2native_int16(ldns_rr_rdf(nsec3_rr, 2));
+	}
+	return 0;
+	
+}
+
+ldns_rdf *
+ldns_nsec3_salt(const ldns_rr *nsec3_rr)
+{
+	if (nsec3_rr && 
+	      (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
+	       ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
+	    ) {
+		return ldns_rr_rdf(nsec3_rr, 3);
+	}
+	return NULL;
+}
+
+uint8_t
+ldns_nsec3_salt_length(const ldns_rr *nsec3_rr)
+{
+	ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr);
+	if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) {
+		return (uint8_t) ldns_rdf_data(salt_rdf)[0];
+	}
+	return 0;
+}
+
+/* allocs data, free with LDNS_FREE() */
+uint8_t *
+ldns_nsec3_salt_data(const ldns_rr *nsec3_rr)
+{
+	uint8_t salt_length;
+	uint8_t *salt;
+
+	ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr);
+	if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) {
+	    	salt_length = ldns_rdf_data(salt_rdf)[0];
+		salt = LDNS_XMALLOC(uint8_t, salt_length);
+                if(!salt) return NULL;
+		memcpy(salt, &ldns_rdf_data(salt_rdf)[1], salt_length);
+		return salt;
+	}
+	return NULL;
+}
+
+ldns_rdf *
+ldns_nsec3_next_owner(const ldns_rr *nsec3_rr)
+{
+	if (!nsec3_rr || ldns_rr_get_type(nsec3_rr) != LDNS_RR_TYPE_NSEC3) {
+		return NULL;
+	} else {
+		return ldns_rr_rdf(nsec3_rr, 4);
+	}
+}
+
+ldns_rdf *
+ldns_nsec3_bitmap(const ldns_rr *nsec3_rr)
+{
+	if (!nsec3_rr || ldns_rr_get_type(nsec3_rr) != LDNS_RR_TYPE_NSEC3) {
+		return NULL;
+	} else {
+		return ldns_rr_rdf(nsec3_rr, 5);
+	}
+}
+
+ldns_rdf *
+ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name)
+{
+	uint8_t algorithm;
+	uint16_t iterations;
+	uint8_t salt_length;
+	uint8_t *salt = 0;
+
+	ldns_rdf *hashed_owner;
+
+	algorithm = ldns_nsec3_algorithm(nsec);
+	salt_length = ldns_nsec3_salt_length(nsec);
+	salt = ldns_nsec3_salt_data(nsec);
+	iterations = ldns_nsec3_iterations(nsec);
+
+	hashed_owner = ldns_nsec3_hash_name(name,
+								 algorithm,
+								 iterations,
+								 salt_length,
+								 salt);
+
+	LDNS_FREE(salt);
+	return hashed_owner;
+}
+
+bool
+ldns_nsec_bitmap_covers_type(const  ldns_rdf* bitmap, ldns_rr_type type)
+{
+	uint8_t* dptr;
+	uint8_t* dend;
+
+	/* From RFC3845 Section 2.1.2:
+	 *
+	 *	"The RR type space is split into 256 window blocks, each re-
+	 *	 presenting the low-order 8 bits of the 16-bit RR type space."
+	 */
+	uint8_t  window = type >> 8;
+	uint8_t subtype = type & 0xff;
+
+	if (! bitmap) {
+		return false;
+	}
+	assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
+
+	dptr = ldns_rdf_data(bitmap);
+	dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
+
+	/* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
+	 *                 dptr[0]          dptr[1]         dptr[2:]
+	 */
+	while (dptr < dend && dptr[0] <= window) {
+
+		if (dptr[0] == window && subtype / 8 < dptr[1] &&
+				dptr + dptr[1] + 2 <= dend) {
+
+			return dptr[2 + subtype / 8] & (0x80 >> (subtype % 8));
+		}
+		dptr += dptr[1] + 2; /* next window */
+	}
+	return false;
+}
+
+ldns_status
+ldns_nsec_bitmap_set_type(ldns_rdf* bitmap, ldns_rr_type type)
+{
+	uint8_t* dptr;
+	uint8_t* dend;
+
+	/* From RFC3845 Section 2.1.2:
+	 *
+	 *	"The RR type space is split into 256 window blocks, each re-
+	 *	 presenting the low-order 8 bits of the 16-bit RR type space."
+	 */
+	uint8_t  window = type >> 8;
+	uint8_t subtype = type & 0xff;
+
+	if (! bitmap) {
+		return false;
+	}
+	assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
+
+	dptr = ldns_rdf_data(bitmap);
+	dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
+
+	/* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
+	 *                 dptr[0]          dptr[1]         dptr[2:]
+	 */
+	while (dptr < dend && dptr[0] <= window) {
+
+		if (dptr[0] == window && subtype / 8 < dptr[1] &&
+				dptr + dptr[1] + 2 <= dend) {
+
+			dptr[2 + subtype / 8] |= (0x80 >> (subtype % 8));
+			return LDNS_STATUS_OK;
+		}
+		dptr += dptr[1] + 2; /* next window */
+	}
+	return LDNS_STATUS_TYPE_NOT_IN_BITMAP;
+}
+
+ldns_status
+ldns_nsec_bitmap_clear_type(ldns_rdf* bitmap, ldns_rr_type type)
+{
+	uint8_t* dptr;
+	uint8_t* dend;
+
+	/* From RFC3845 Section 2.1.2:
+	 *
+	 *	"The RR type space is split into 256 window blocks, each re-
+	 *	 presenting the low-order 8 bits of the 16-bit RR type space."
+	 */
+	uint8_t  window = type >> 8;
+	uint8_t subtype = type & 0xff;
+
+	if (! bitmap) {
+		return false;
+	}
+
+	assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
+
+	dptr = ldns_rdf_data(bitmap);
+	dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
+
+	/* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
+	 *                 dptr[0]          dptr[1]         dptr[2:]
+	 */
+	while (dptr < dend && dptr[0] <= window) {
+
+		if (dptr[0] == window && subtype / 8 < dptr[1] &&
+				dptr + dptr[1] + 2 <= dend) {
+
+			dptr[2 + subtype / 8] &= ~(0x80 >> (subtype % 8));
+			return LDNS_STATUS_OK;
+		}
+		dptr += dptr[1] + 2; /* next window */
+	}
+	return LDNS_STATUS_TYPE_NOT_IN_BITMAP;
+}
+
+
+bool
+ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
+{
+	ldns_rdf *nsec_owner = ldns_rr_owner(nsec);
+	ldns_rdf *hash_next;
+	char *next_hash_str;
+	ldns_rdf *nsec_next = NULL;
+	ldns_status status;
+	ldns_rdf *chopped_dname;
+	bool result;
+
+	if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
+		if (ldns_rr_rdf(nsec, 0) != NULL) {
+			nsec_next = ldns_rdf_clone(ldns_rr_rdf(nsec, 0));
+		} else {
+			return false;
+		}
+	} else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
+		hash_next = ldns_nsec3_next_owner(nsec);
+		next_hash_str = ldns_rdf2str(hash_next);
+		nsec_next = ldns_dname_new_frm_str(next_hash_str);
+		LDNS_FREE(next_hash_str);
+		chopped_dname = ldns_dname_left_chop(nsec_owner);
+		status = ldns_dname_cat(nsec_next, chopped_dname);
+		ldns_rdf_deep_free(chopped_dname);
+		if (status != LDNS_STATUS_OK) {
+			printf("error catting: %s\n", ldns_get_errorstr_by_id(status));
+		}
+	} else {
+		ldns_rdf_deep_free(nsec_next);
+		return false;
+	}
+
+	/* in the case of the last nsec */
+	if(ldns_dname_compare(nsec_owner, nsec_next) > 0) {
+		result = (ldns_dname_compare(nsec_owner, name) <= 0 ||
+				ldns_dname_compare(name, nsec_next) < 0);
+	} else if(ldns_dname_compare(nsec_owner, nsec_next) < 0) {
+		result = (ldns_dname_compare(nsec_owner, name) <= 0 &&
+		          ldns_dname_compare(name, nsec_next) < 0);
+	} else {
+		result = true;
+	}
+
+	ldns_rdf_deep_free(nsec_next);
+	return result;
+}
+
+#ifdef HAVE_SSL
+/* sig may be null - if so look in the packet */
+
+ldns_status
+ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, 
+		ldns_rr_list *k, ldns_rr_list *s, 
+		time_t check_time, ldns_rr_list *good_keys)
+{
+	ldns_rr_list *rrset;
+	ldns_rr_list *sigs;
+	ldns_rr_list *sigs_covered;
+	ldns_rdf *rdf_t;
+	ldns_rr_type t_netorder;
+
+	if (!k) {
+		return LDNS_STATUS_ERR;
+		/* return LDNS_STATUS_CRYPTO_NO_DNSKEY; */
+	}
+
+	if (t == LDNS_RR_TYPE_RRSIG) {
+		/* we don't have RRSIG(RRSIG) (yet? ;-) ) */
+		return LDNS_STATUS_ERR;
+	}
+
+	if (s) {
+		/* if s is not NULL, the sigs are given to use */
+		sigs = s;
+	} else {
+		/* otherwise get them from the packet */
+		sigs = ldns_pkt_rr_list_by_name_and_type(p, o,
+				LDNS_RR_TYPE_RRSIG,
+				LDNS_SECTION_ANY_NOQUESTION);
+		if (!sigs) {
+			/* no sigs */
+			return LDNS_STATUS_ERR;
+			/* return LDNS_STATUS_CRYPTO_NO_RRSIG; */
+		}
+	}
+
+	/* rrsig are subtyped, so now we need to find the correct
+	 * sigs for the type t
+	 */
+	t_netorder = htons(t); /* rdf are in network order! */
+	/* a type identifier is a 16-bit number, so the size is 2 bytes */
+	rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, 2, &t_netorder);
+
+	sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
+	ldns_rdf_free(rdf_t);
+	if (! sigs_covered) {
+		if (! s) {
+			ldns_rr_list_deep_free(sigs);
+		}
+		return LDNS_STATUS_ERR;
+	}
+	ldns_rr_list_deep_free(sigs_covered);
+
+	rrset = ldns_pkt_rr_list_by_name_and_type(p, o, t,
+			LDNS_SECTION_ANY_NOQUESTION);
+	if (!rrset) {
+		if (! s) {
+			ldns_rr_list_deep_free(sigs);
+		}
+		return LDNS_STATUS_ERR;
+	}
+	return ldns_verify_time(rrset, sigs, k, check_time, good_keys);
+}
+
+ldns_status
+ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, 
+		ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys)
+{
+	return ldns_pkt_verify_time(p, t, o, k, s, ldns_time(NULL), good_keys);
+}
+#endif /* HAVE_SSL */
+
+ldns_status
+ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs)
+{
+	size_t i;
+	char *next_nsec_owner_str;
+	ldns_rdf *next_nsec_owner_label;
+	ldns_rdf *next_nsec_rdf;
+	ldns_status status = LDNS_STATUS_OK;
+
+	for (i = 0; i < ldns_rr_list_rr_count(nsec3_rrs); i++) {
+		if (i == ldns_rr_list_rr_count(nsec3_rrs) - 1) {
+			next_nsec_owner_label =
+				ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(nsec3_rrs,
+													  0)), 0);
+			next_nsec_owner_str = ldns_rdf2str(next_nsec_owner_label);
+			if (next_nsec_owner_str[strlen(next_nsec_owner_str) - 1]
+			    == '.') {
+				next_nsec_owner_str[strlen(next_nsec_owner_str) - 1]
+					= '\0';
+			}
+			status = ldns_str2rdf_b32_ext(&next_nsec_rdf,
+									next_nsec_owner_str);
+			if (!ldns_rr_set_rdf(ldns_rr_list_rr(nsec3_rrs, i),
+							 next_nsec_rdf, 4)) {
+				/* todo: error */
+			}
+
+			ldns_rdf_deep_free(next_nsec_owner_label);
+			LDNS_FREE(next_nsec_owner_str);
+		} else {
+			next_nsec_owner_label =
+				ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(nsec3_rrs,
+													  i + 1)),
+							  0);
+			next_nsec_owner_str = ldns_rdf2str(next_nsec_owner_label);
+			if (next_nsec_owner_str[strlen(next_nsec_owner_str) - 1]
+			    == '.') {
+				next_nsec_owner_str[strlen(next_nsec_owner_str) - 1]
+					= '\0';
+			}
+			status = ldns_str2rdf_b32_ext(&next_nsec_rdf,
+									next_nsec_owner_str);
+			ldns_rdf_deep_free(next_nsec_owner_label);
+			LDNS_FREE(next_nsec_owner_str);
+			if (!ldns_rr_set_rdf(ldns_rr_list_rr(nsec3_rrs, i),
+							 next_nsec_rdf, 4)) {
+				/* todo: error */
+			}
+		}
+	}
+	return status;
+}
+
+int
+qsort_rr_compare_nsec3(const void *a, const void *b)
+{
+	const ldns_rr *rr1 = * (const ldns_rr **) a;
+	const ldns_rr *rr2 = * (const ldns_rr **) b;
+	if (rr1 == NULL && rr2 == NULL) {
+		return 0;
+	}
+	if (rr1 == NULL) {
+		return -1;
+	}
+	if (rr2 == NULL) {
+		return 1;
+	}
+	return ldns_rdf_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2));
+}
+
+void
+ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted)
+{
+	qsort(unsorted->_rrs,
+	      ldns_rr_list_rr_count(unsorted),
+	      sizeof(ldns_rr *),
+	      qsort_rr_compare_nsec3);
+}
+
+int
+ldns_dnssec_default_add_to_signatures( ATTR_UNUSED(ldns_rr *sig)
+				     , ATTR_UNUSED(void *n)
+				     )
+{
+	return LDNS_SIGNATURE_LEAVE_ADD_NEW;
+}
+
+int
+ldns_dnssec_default_leave_signatures( ATTR_UNUSED(ldns_rr *sig)
+				    , ATTR_UNUSED(void *n)
+				    )
+{
+	return LDNS_SIGNATURE_LEAVE_NO_ADD;
+}
+
+int
+ldns_dnssec_default_delete_signatures( ATTR_UNUSED(ldns_rr *sig)
+				     , ATTR_UNUSED(void *n)
+				     )
+{
+	return LDNS_SIGNATURE_REMOVE_NO_ADD;
+}
+
+int
+ldns_dnssec_default_replace_signatures( ATTR_UNUSED(ldns_rr *sig)
+				      , ATTR_UNUSED(void *n)
+				      )
+{
+	return LDNS_SIGNATURE_REMOVE_ADD_NEW;
+}
+
+#ifdef HAVE_SSL
+ldns_rdf *
+ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
+						  const long sig_len)
+{
+	ldns_rdf *sigdata_rdf;
+	DSA_SIG *dsasig;
+	unsigned char *dsasig_data = (unsigned char*)ldns_buffer_begin(sig);
+	size_t byte_offset;
+
+	dsasig = d2i_DSA_SIG(NULL,
+					 (const unsigned char **)&dsasig_data,
+					 sig_len);
+	if (!dsasig) {
+                DSA_SIG_free(dsasig);
+		return NULL;
+	}
+
+	dsasig_data = LDNS_XMALLOC(unsigned char, 41);
+        if(!dsasig_data) {
+                DSA_SIG_free(dsasig);
+                return NULL;
+        }
+	dsasig_data[0] = 0;
+	byte_offset = (size_t) (20 - BN_num_bytes(dsasig->r));
+	if (byte_offset > 20) {
+                DSA_SIG_free(dsasig);
+                LDNS_FREE(dsasig_data);
+		return NULL;
+	}
+	memset(&dsasig_data[1], 0, byte_offset);
+	BN_bn2bin(dsasig->r, &dsasig_data[1 + byte_offset]);
+	byte_offset = (size_t) (20 - BN_num_bytes(dsasig->s));
+	if (byte_offset > 20) {
+                DSA_SIG_free(dsasig);
+                LDNS_FREE(dsasig_data);
+		return NULL;
+	}
+	memset(&dsasig_data[21], 0, byte_offset);
+	BN_bn2bin(dsasig->s, &dsasig_data[21 + byte_offset]);
+
+	sigdata_rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, 41, dsasig_data);
+        if(!sigdata_rdf) {
+                LDNS_FREE(dsasig_data);
+        }
+	DSA_SIG_free(dsasig);
+
+	return sigdata_rdf;
+}
+
+ldns_status
+ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+						  const ldns_rdf *sig_rdf)
+{
+	/* the EVP api wants the DER encoding of the signature... */
+	BIGNUM *R, *S;
+	DSA_SIG *dsasig;
+	unsigned char *raw_sig = NULL;
+	int raw_sig_len;
+
+        if(ldns_rdf_size(sig_rdf) < 1 + 2*SHA_DIGEST_LENGTH)
+                return LDNS_STATUS_SYNTAX_RDATA_ERR;
+	/* extract the R and S field from the sig buffer */
+	R = BN_new();
+	if(!R) return LDNS_STATUS_MEM_ERR;
+	(void) BN_bin2bn((unsigned char *) ldns_rdf_data(sig_rdf) + 1,
+	                 SHA_DIGEST_LENGTH, R);
+	S = BN_new();
+	if(!S) {
+		BN_free(R);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	(void) BN_bin2bn((unsigned char *) ldns_rdf_data(sig_rdf) + 21,
+	                 SHA_DIGEST_LENGTH, S);
+
+	dsasig = DSA_SIG_new();
+	if (!dsasig) {
+		BN_free(R);
+		BN_free(S);
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	dsasig->r = R;
+	dsasig->s = S;
+
+	raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig);
+	if (raw_sig_len < 0) {
+		DSA_SIG_free(dsasig);
+		free(raw_sig);
+		return LDNS_STATUS_SSL_ERR;
+	}
+	if (ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) {
+		ldns_buffer_write(target_buffer, raw_sig, (size_t)raw_sig_len);
+	}
+
+	DSA_SIG_free(dsasig);
+	free(raw_sig);
+
+	return ldns_buffer_status(target_buffer);
+}
+
+#ifdef USE_ECDSA
+#ifndef S_SPLINT_S
+ldns_rdf *
+ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len)
+{
+        ECDSA_SIG* ecdsa_sig;
+	unsigned char *data = (unsigned char*)ldns_buffer_begin(sig);
+        ldns_rdf* rdf;
+	ecdsa_sig = d2i_ECDSA_SIG(NULL, (const unsigned char **)&data, sig_len);
+        if(!ecdsa_sig) return NULL;
+
+        /* "r | s". */
+        data = LDNS_XMALLOC(unsigned char,
+                BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s));
+        if(!data) {
+                ECDSA_SIG_free(ecdsa_sig);
+                return NULL;
+        }
+        BN_bn2bin(ecdsa_sig->r, data);
+        BN_bn2bin(ecdsa_sig->s, data+BN_num_bytes(ecdsa_sig->r));
+	rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, (size_t)(
+		BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s)), data);
+        ECDSA_SIG_free(ecdsa_sig);
+        return rdf;
+}
+
+ldns_status
+ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+        const ldns_rdf *sig_rdf)
+{
+        ECDSA_SIG* sig;
+	int raw_sig_len;
+        long bnsize = (long)ldns_rdf_size(sig_rdf) / 2;
+        /* if too short, or not even length, do not bother */
+        if(bnsize < 16 || (size_t)bnsize*2 != ldns_rdf_size(sig_rdf))
+                return LDNS_STATUS_ERR;
+        
+        /* use the raw data to parse two evenly long BIGNUMs, "r | s". */
+        sig = ECDSA_SIG_new();
+        if(!sig) return LDNS_STATUS_MEM_ERR;
+        sig->r = BN_bin2bn((const unsigned char*)ldns_rdf_data(sig_rdf),
+                bnsize, sig->r);
+        sig->s = BN_bin2bn((const unsigned char*)ldns_rdf_data(sig_rdf)+bnsize,
+                bnsize, sig->s);
+        if(!sig->r || !sig->s) {
+                ECDSA_SIG_free(sig);
+                return LDNS_STATUS_MEM_ERR;
+        }
+
+	raw_sig_len = i2d_ECDSA_SIG(sig, NULL);
+	if (ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) {
+                unsigned char* pp = (unsigned char*)
+			ldns_buffer_current(target_buffer);
+	        raw_sig_len = i2d_ECDSA_SIG(sig, &pp);
+                ldns_buffer_skip(target_buffer, (ssize_t) raw_sig_len);
+	}
+        ECDSA_SIG_free(sig);
+
+	return ldns_buffer_status(target_buffer);
+}
+
+#endif /* S_SPLINT_S */
+#endif /* USE_ECDSA */
+#endif /* HAVE_SSL */
diff --git a/ldns/src/dnssec_sign.c b/ldns/src/dnssec_sign.c
new file mode 100644
index 0000000..4af882a
--- /dev/null
+++ b/ldns/src/dnssec_sign.c
@@ -0,0 +1,1456 @@
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <ldns/dnssec.h>
+#include <ldns/dnssec_sign.h>
+
+#include <strings.h>
+#include <time.h>
+
+#ifdef HAVE_SSL
+/* this entire file is rather useless when you don't have
+ * crypto...
+ */
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/md5.h>
+#endif /* HAVE_SSL */
+
+ldns_rr *
+ldns_create_empty_rrsig(ldns_rr_list *rrset,
+                        ldns_key *current_key)
+{
+	uint32_t orig_ttl;
+	ldns_rr_class orig_class;
+	time_t now;
+	ldns_rr *current_sig;
+	uint8_t label_count;
+	ldns_rdf *signame;
+
+	label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
+	                                                   0)));
+        /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
+        if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
+                label_count --;
+
+	current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
+
+	/* set the type on the new signature */
+	orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
+	orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
+
+	ldns_rr_set_ttl(current_sig, orig_ttl);
+	ldns_rr_set_class(current_sig, orig_class);
+	ldns_rr_set_owner(current_sig,
+			  ldns_rdf_clone(
+			       ldns_rr_owner(
+				    ldns_rr_list_rr(rrset,
+						    0))));
+
+	/* fill in what we know of the signature */
+
+	/* set the orig_ttl */
+	(void)ldns_rr_rrsig_set_origttl(
+		   current_sig,
+		   ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
+					 orig_ttl));
+	/* the signers name */
+	signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
+	ldns_dname2canonical(signame);
+	(void)ldns_rr_rrsig_set_signame(
+			current_sig,
+			signame);
+	/* label count - get it from the first rr in the rr_list */
+	(void)ldns_rr_rrsig_set_labels(
+			current_sig,
+			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
+			                     label_count));
+	/* inception, expiration */
+	now = time(NULL);
+	if (ldns_key_inception(current_key) != 0) {
+		(void)ldns_rr_rrsig_set_inception(
+				current_sig,
+				ldns_native2rdf_int32(
+				    LDNS_RDF_TYPE_TIME,
+				    ldns_key_inception(current_key)));
+	} else {
+		(void)ldns_rr_rrsig_set_inception(
+				current_sig,
+				ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
+	}
+	if (ldns_key_expiration(current_key) != 0) {
+		(void)ldns_rr_rrsig_set_expiration(
+				current_sig,
+				ldns_native2rdf_int32(
+				    LDNS_RDF_TYPE_TIME,
+				    ldns_key_expiration(current_key)));
+	} else {
+		(void)ldns_rr_rrsig_set_expiration(
+			     current_sig,
+				ldns_native2rdf_int32(
+				    LDNS_RDF_TYPE_TIME,
+				    now + LDNS_DEFAULT_EXP_TIME));
+	}
+
+	(void)ldns_rr_rrsig_set_keytag(
+		   current_sig,
+		   ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
+		                         ldns_key_keytag(current_key)));
+
+	(void)ldns_rr_rrsig_set_algorithm(
+			current_sig,
+			ldns_native2rdf_int8(
+			    LDNS_RDF_TYPE_ALG,
+			    ldns_key_algorithm(current_key)));
+
+	(void)ldns_rr_rrsig_set_typecovered(
+			current_sig,
+			ldns_native2rdf_int16(
+			    LDNS_RDF_TYPE_TYPE,
+			    ldns_rr_get_type(ldns_rr_list_rr(rrset,
+			                                     0))));
+	return current_sig;
+}
+
+#ifdef HAVE_SSL
+ldns_rdf *
+ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
+{
+	ldns_rdf *b64rdf = NULL;
+
+	switch(ldns_key_algorithm(current_key)) {
+	case LDNS_SIGN_DSA:
+	case LDNS_SIGN_DSA_NSEC3:
+		b64rdf = ldns_sign_public_evp(
+				   sign_buf,
+				   ldns_key_evp_key(current_key),
+				   EVP_dss1());
+		break;
+	case LDNS_SIGN_RSASHA1:
+	case LDNS_SIGN_RSASHA1_NSEC3:
+		b64rdf = ldns_sign_public_evp(
+				   sign_buf,
+				   ldns_key_evp_key(current_key),
+				   EVP_sha1());
+		break;
+#ifdef USE_SHA2
+	case LDNS_SIGN_RSASHA256:
+		b64rdf = ldns_sign_public_evp(
+				   sign_buf,
+				   ldns_key_evp_key(current_key),
+				   EVP_sha256());
+		break;
+	case LDNS_SIGN_RSASHA512:
+		b64rdf = ldns_sign_public_evp(
+				   sign_buf,
+				   ldns_key_evp_key(current_key),
+				   EVP_sha512());
+		break;
+#endif /* USE_SHA2 */
+#ifdef USE_GOST
+	case LDNS_SIGN_ECC_GOST:
+		b64rdf = ldns_sign_public_evp(
+				   sign_buf,
+				   ldns_key_evp_key(current_key),
+				   EVP_get_digestbyname("md_gost94"));
+		break;
+#endif /* USE_GOST */
+#ifdef USE_ECDSA
+        case LDNS_SIGN_ECDSAP256SHA256:
+       		b64rdf = ldns_sign_public_evp(
+				   sign_buf,
+				   ldns_key_evp_key(current_key),
+				   EVP_sha256());
+                break;
+        case LDNS_SIGN_ECDSAP384SHA384:
+       		b64rdf = ldns_sign_public_evp(
+				   sign_buf,
+				   ldns_key_evp_key(current_key),
+				   EVP_sha384());
+                break;
+#endif
+	case LDNS_SIGN_RSAMD5:
+		b64rdf = ldns_sign_public_evp(
+				   sign_buf,
+				   ldns_key_evp_key(current_key),
+				   EVP_md5());
+		break;
+	default:
+		/* do _you_ know this alg? */
+		printf("unknown algorithm, ");
+		printf("is the one used available on this system?\n");
+		break;
+	}
+
+	return b64rdf;
+}
+
+/**
+ * use this function to sign with a public/private key alg
+ * return the created signatures
+ */
+ldns_rr_list *
+ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
+{
+	ldns_rr_list *signatures;
+	ldns_rr_list *rrset_clone;
+	ldns_rr *current_sig;
+	ldns_rdf *b64rdf;
+	ldns_key *current_key;
+	size_t key_count;
+	uint16_t i;
+	ldns_buffer *sign_buf;
+	ldns_rdf *new_owner;
+
+	if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
+		return NULL;
+	}
+
+	new_owner = NULL;
+
+	signatures = ldns_rr_list_new();
+
+	/* prepare a signature and add all the know data
+	 * prepare the rrset. Sign this together.  */
+	rrset_clone = ldns_rr_list_clone(rrset);
+	if (!rrset_clone) {
+		return NULL;
+	}
+
+	/* make it canonical */
+	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
+		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), 
+			ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
+		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
+	}
+	/* sort */
+	ldns_rr_list_sort(rrset_clone);
+
+	for (key_count = 0;
+		key_count < ldns_key_list_key_count(keys);
+		key_count++) {
+		if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
+			continue;
+		}
+		sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+		if (!sign_buf) {
+			ldns_rr_list_free(rrset_clone);
+			ldns_rr_list_free(signatures);
+			ldns_rdf_free(new_owner);
+			return NULL;
+		}
+		b64rdf = NULL;
+
+		current_key = ldns_key_list_key(keys, key_count);
+		/* sign all RRs with keys that have ZSKbit, !SEPbit.
+		   sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
+		if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
+			current_sig = ldns_create_empty_rrsig(rrset_clone,
+			                                      current_key);
+
+			/* right now, we have: a key, a semi-sig and an rrset. For
+			 * which we can create the sig and base64 encode that and
+			 * add that to the signature */
+
+			if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
+			    != LDNS_STATUS_OK) {
+				ldns_buffer_free(sign_buf);
+				/* ERROR */
+				ldns_rr_list_deep_free(rrset_clone);
+				ldns_rr_free(current_sig);
+				ldns_rr_list_deep_free(signatures);
+				return NULL;
+			}
+
+			/* add the rrset in sign_buf */
+			if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
+			    != LDNS_STATUS_OK) {
+				ldns_buffer_free(sign_buf);
+				ldns_rr_list_deep_free(rrset_clone);
+				ldns_rr_free(current_sig);
+				ldns_rr_list_deep_free(signatures);
+				return NULL;
+			}
+
+			b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
+
+			if (!b64rdf) {
+				/* signing went wrong */
+				ldns_rr_list_deep_free(rrset_clone);
+				ldns_rr_free(current_sig);
+				ldns_rr_list_deep_free(signatures);
+				return NULL;
+			}
+
+			ldns_rr_rrsig_set_sig(current_sig, b64rdf);
+
+			/* push the signature to the signatures list */
+			ldns_rr_list_push_rr(signatures, current_sig);
+		}
+		ldns_buffer_free(sign_buf); /* restart for the next key */
+	}
+	ldns_rr_list_deep_free(rrset_clone);
+
+	return signatures;
+}
+
+/**
+ * Sign data with DSA
+ *
+ * \param[in] to_sign The ldns_buffer containing raw data that is
+ *                    to be signed
+ * \param[in] key The DSA key structure to sign with
+ * \return ldns_rdf for the RRSIG ldns_rr
+ */
+ldns_rdf *
+ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
+{
+	unsigned char *sha1_hash;
+	ldns_rdf *sigdata_rdf;
+	ldns_buffer *b64sig;
+
+	DSA_SIG *sig;
+	uint8_t *data;
+	size_t pad;
+
+	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	if (!b64sig) {
+		return NULL;
+	}
+
+	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
+				  ldns_buffer_position(to_sign), NULL);
+	if (!sha1_hash) {
+		ldns_buffer_free(b64sig);
+		return NULL;
+	}
+
+	sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
+        if(!sig) {
+		ldns_buffer_free(b64sig);
+		return NULL;
+        }
+
+	data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
+        if(!data) {
+		ldns_buffer_free(b64sig);
+                DSA_SIG_free(sig);
+		return NULL;
+        }
+
+	data[0] = 1;
+	pad = 20 - (size_t) BN_num_bytes(sig->r);
+	if (pad > 0) {
+		memset(data + 1, 0, pad);
+	}
+	BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
+
+	pad = 20 - (size_t) BN_num_bytes(sig->s);
+	if (pad > 0) {
+		memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
+	}
+	BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
+
+	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
+								 1 + 2 * SHA_DIGEST_LENGTH,
+								 data);
+
+	ldns_buffer_free(b64sig);
+	LDNS_FREE(data);
+        DSA_SIG_free(sig);
+
+	return sigdata_rdf;
+}
+
+#ifdef USE_ECDSA
+#ifndef S_SPLINT_S
+static int
+ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
+{
+        EC_KEY* ec;
+        const EC_GROUP* g;
+        if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
+                return 0;
+        ec = EVP_PKEY_get1_EC_KEY(pkey);
+        g = EC_KEY_get0_group(ec);
+        if(!g) {
+                EC_KEY_free(ec);
+                return 0;
+        }
+        if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
+                EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
+                EC_GROUP_get_curve_name(g) == NID_secp384r1) {
+                EC_KEY_free(ec);
+                return 1;
+        }
+        /* downref the eckey, the original is still inside the pkey */
+        EC_KEY_free(ec);
+        return 0;
+}
+#endif /* splint */
+#endif /* USE_ECDSA */
+
+ldns_rdf *
+ldns_sign_public_evp(ldns_buffer *to_sign,
+				 EVP_PKEY *key,
+				 const EVP_MD *digest_type)
+{
+	unsigned int siglen;
+	ldns_rdf *sigdata_rdf;
+	ldns_buffer *b64sig;
+	EVP_MD_CTX ctx;
+	const EVP_MD *md_type;
+	int r;
+
+	siglen = 0;
+	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	if (!b64sig) {
+		return NULL;
+	}
+
+	/* initializes a signing context */
+	md_type = digest_type;
+	if(!md_type) {
+		/* unknown message difest */
+		ldns_buffer_free(b64sig);
+		return NULL;
+	}
+
+	EVP_MD_CTX_init(&ctx);
+	r = EVP_SignInit(&ctx, md_type);
+	if(r == 1) {
+		r = EVP_SignUpdate(&ctx, (unsigned char*)
+					    ldns_buffer_begin(to_sign),
+					    ldns_buffer_position(to_sign));
+	} else {
+		ldns_buffer_free(b64sig);
+		return NULL;
+	}
+	if(r == 1) {
+		r = EVP_SignFinal(&ctx, (unsigned char*)
+					   ldns_buffer_begin(b64sig), &siglen, key);
+	} else {
+		ldns_buffer_free(b64sig);
+		return NULL;
+	}
+	if(r != 1) {
+		ldns_buffer_free(b64sig);
+		return NULL;
+	}
+
+	/* unfortunately, OpenSSL output is differenct from DNS DSA format */
+#ifndef S_SPLINT_S
+	if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
+		sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
+#ifdef USE_ECDSA
+        } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
+                ldns_pkey_is_ecdsa(key)) {
+                sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
+#endif
+	} else {
+		/* ok output for other types is the same */
+		sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
+									 ldns_buffer_begin(b64sig));
+	}
+#endif /* splint */
+	ldns_buffer_free(b64sig);
+	EVP_MD_CTX_cleanup(&ctx);
+	return sigdata_rdf;
+}
+
+ldns_rdf *
+ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
+{
+	unsigned char *sha1_hash;
+	unsigned int siglen;
+	ldns_rdf *sigdata_rdf;
+	ldns_buffer *b64sig;
+	int result;
+
+	siglen = 0;
+	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	if (!b64sig) {
+		return NULL;
+	}
+
+	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
+				  ldns_buffer_position(to_sign), NULL);
+	if (!sha1_hash) {
+		ldns_buffer_free(b64sig);
+		return NULL;
+	}
+
+	result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
+				   (unsigned char*)ldns_buffer_begin(b64sig),
+				   &siglen, key);
+	if (result != 1) {
+		ldns_buffer_free(b64sig);
+		return NULL;
+	}
+
+	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 
+								 ldns_buffer_begin(b64sig));
+	ldns_buffer_free(b64sig); /* can't free this buffer ?? */
+	return sigdata_rdf;
+}
+
+ldns_rdf *
+ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
+{
+	unsigned char *md5_hash;
+	unsigned int siglen;
+	ldns_rdf *sigdata_rdf;
+	ldns_buffer *b64sig;
+
+	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	if (!b64sig) {
+		return NULL;
+	}
+
+	md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
+				ldns_buffer_position(to_sign), NULL);
+	if (!md5_hash) {
+		ldns_buffer_free(b64sig);
+		return NULL;
+	}
+
+	RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
+		    (unsigned char*)ldns_buffer_begin(b64sig),
+		    &siglen, key);
+
+	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
+								 ldns_buffer_begin(b64sig));
+	ldns_buffer_free(b64sig);
+	return sigdata_rdf;
+}
+#endif /* HAVE_SSL */
+
+/**
+ * Pushes all rrs from the rrsets of type A and AAAA on gluelist.
+ */
+static ldns_status
+ldns_dnssec_addresses_on_glue_list(
+		ldns_dnssec_rrsets *cur_rrset,
+		ldns_rr_list *glue_list)
+{
+	ldns_dnssec_rrs *cur_rrs;
+	while (cur_rrset) {
+		if (cur_rrset->type == LDNS_RR_TYPE_A 
+				|| cur_rrset->type == LDNS_RR_TYPE_AAAA) {
+			for (cur_rrs = cur_rrset->rrs; 
+					cur_rrs; 
+					cur_rrs = cur_rrs->next) {
+				if (cur_rrs->rr) {
+					if (!ldns_rr_list_push_rr(glue_list, 
+							cur_rrs->rr)) {
+						return LDNS_STATUS_MEM_ERR; 
+						/* ldns_rr_list_push_rr()
+						 * returns false when unable
+						 * to increase the capacity
+						 * of the ldsn_rr_list
+						 */
+					}
+				}
+			}
+		}
+		cur_rrset = cur_rrset->next;
+	}
+	return LDNS_STATUS_OK;
+}
+
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially occluded (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account separately.
+ *
+ * When glue_list is given (not NULL), in the process of marking the names, all
+ * glue resource records will be pushed to that list, even glue at delegation names.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \param[in] glue_list the list to which to push the glue rrs
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status
+ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 
+	ldns_rr_list *glue_list)
+{
+	ldns_rbnode_t    *node;
+	ldns_dnssec_name *name;
+	ldns_rdf         *owner;
+	ldns_rdf         *cut = NULL; /* keeps track of zone cuts */
+	/* When the cut is caused by a delegation, below_delegation will be 1.
+	 * When caused by a DNAME, below_delegation will be 0.
+	 */
+	int below_delegation = -1; /* init suppresses comiler warning */
+	ldns_status s;
+
+	if (!zone || !zone->names) {
+		return LDNS_STATUS_NULL;
+	}
+	for (node = ldns_rbtree_first(zone->names); 
+			node != LDNS_RBTREE_NULL; 
+			node = ldns_rbtree_next(node)) {
+		name = (ldns_dnssec_name *) node->data;
+		owner = ldns_dnssec_name_name(name);
+
+		if (cut) { 
+			/* The previous node was a zone cut, or a subdomain
+			 * below a zone cut. Is this node (still) a subdomain
+			 * below the cut? Then the name is occluded. Unless
+			 * the name contains a SOA, after which we are 
+			 * authoritative again.
+			 *
+			 * FIXME! If there are labels in between the SOA and
+			 * the cut, going from the authoritative space (below
+			 * the SOA) up into occluded space again, will not be
+			 * detected with the contruct below!
+			 */
+			if (ldns_dname_is_subdomain(owner, cut) &&
+					!ldns_dnssec_rrsets_contains_type(
+					name->rrsets, LDNS_RR_TYPE_SOA)) {
+
+				if (below_delegation && glue_list) {
+					s = ldns_dnssec_addresses_on_glue_list(
+						name->rrsets, glue_list);
+					if (s != LDNS_STATUS_OK) {
+						return s;
+					}
+				}
+				name->is_glue = true; /* Mark occluded name! */
+				continue;
+			} else {
+				cut = NULL;
+			}
+		}
+
+		/* The node is not below a zone cut. Is it a zone cut itself?
+		 * Everything below a SOA is authoritative of course; Except
+		 * when the name also contains a DNAME :).
+		 */
+		if (ldns_dnssec_rrsets_contains_type(
+				name->rrsets, LDNS_RR_TYPE_NS)
+			    && !ldns_dnssec_rrsets_contains_type(
+				name->rrsets, LDNS_RR_TYPE_SOA)) {
+			cut = owner;
+			below_delegation = 1;
+			if (glue_list) { /* record glue on the zone cut */
+				s = ldns_dnssec_addresses_on_glue_list(
+					name->rrsets, glue_list);
+				if (s != LDNS_STATUS_OK) {
+					return s;
+				}
+			}
+		} else if (ldns_dnssec_rrsets_contains_type(
+				name->rrsets, LDNS_RR_TYPE_DNAME)) {
+			cut = owner;
+			below_delegation = 0;
+		}
+	}
+	return LDNS_STATUS_OK;
+}
+
+/**
+ * Marks the names in the zone that are occluded. Those names will be skipped
+ * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
+ * function. But watch out! Names that are partially occluded (like glue with
+ * the same name as the delegation) will not be marked and should specifically 
+ * be taken into account separately.
+ *
+ * \param[in] zone the zone in which to mark the names
+ * \return LDNS_STATUS_OK on success, an error code otherwise
+ */
+ldns_status
+ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
+{
+	return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
+}
+
+ldns_rbnode_t *
+ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
+{
+	ldns_rbnode_t *next_node = NULL;
+	ldns_dnssec_name *next_name = NULL;
+	bool done = false;
+
+	if (node == LDNS_RBTREE_NULL) {
+		return NULL;
+	}
+	next_node = node;
+	while (!done) {
+		if (next_node == LDNS_RBTREE_NULL) {
+			return NULL;
+		} else {
+			next_name = (ldns_dnssec_name *)next_node->data;
+			if (!next_name->is_glue) {
+				done = true;
+			} else {
+				next_node = ldns_rbtree_next(next_node);
+			}
+		}
+	}
+	return next_node;
+}
+
+ldns_status
+ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
+                              ldns_rr_list *new_rrs)
+{
+
+	ldns_rbnode_t *first_node, *cur_node, *next_node;
+	ldns_dnssec_name *cur_name, *next_name;
+	ldns_rr *nsec_rr;
+	uint32_t nsec_ttl;
+	ldns_dnssec_rrsets *soa;
+
+	/* the TTL of NSEC rrs should be set to the minimum TTL of
+	 * the zone SOA (RFC4035 Section 2.3)
+	 */
+	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
+
+	/* did the caller actually set it? if not,
+	 * fall back to default ttl
+	 */
+	if (soa && soa->rrs && soa->rrs->rr
+			&& (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
+		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
+	} else {
+		nsec_ttl = LDNS_DEFAULT_TTL;
+	}
+
+	first_node = ldns_dnssec_name_node_next_nonglue(
+			       ldns_rbtree_first(zone->names));
+	cur_node = first_node;
+	if (cur_node) {
+		next_node = ldns_dnssec_name_node_next_nonglue(
+			           ldns_rbtree_next(cur_node));
+	} else {
+		next_node = NULL;
+	}
+
+	while (cur_node && next_node) {
+		cur_name = (ldns_dnssec_name *)cur_node->data;
+		next_name = (ldns_dnssec_name *)next_node->data;
+		nsec_rr = ldns_dnssec_create_nsec(cur_name,
+		                                  next_name,
+		                                  LDNS_RR_TYPE_NSEC);
+		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
+		if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
+			ldns_rr_free(nsec_rr);
+			return LDNS_STATUS_ERR;
+		}
+		ldns_rr_list_push_rr(new_rrs, nsec_rr);
+		cur_node = next_node;
+		if (cur_node) {
+			next_node = ldns_dnssec_name_node_next_nonglue(
+                               ldns_rbtree_next(cur_node));
+		}
+	}
+
+	if (cur_node && !next_node) {
+		cur_name = (ldns_dnssec_name *)cur_node->data;
+		next_name = (ldns_dnssec_name *)first_node->data;
+		nsec_rr = ldns_dnssec_create_nsec(cur_name,
+		                                  next_name,
+		                                  LDNS_RR_TYPE_NSEC);
+		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
+		if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
+			ldns_rr_free(nsec_rr);
+			return LDNS_STATUS_ERR;
+		}
+		ldns_rr_list_push_rr(new_rrs, nsec_rr);
+	} else {
+		printf("error\n");
+	}
+
+	return LDNS_STATUS_OK;
+}
+
+#ifdef HAVE_SSL
+static void
+ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
+	(void) arg;
+	LDNS_FREE(node);
+}
+
+static ldns_status
+ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
+		ldns_rr_list *new_rrs,
+		uint8_t algorithm,
+		uint8_t flags,
+		uint16_t iterations,
+		uint8_t salt_length,
+		uint8_t *salt,
+		ldns_rbtree_t **map)
+{
+	ldns_rbnode_t *first_name_node;
+	ldns_rbnode_t *current_name_node;
+	ldns_dnssec_name *current_name;
+	ldns_status result = LDNS_STATUS_OK;
+	ldns_rr *nsec_rr;
+	ldns_rr_list *nsec3_list;
+	uint32_t nsec_ttl;
+	ldns_dnssec_rrsets *soa;
+	ldns_rbnode_t *hashmap_node;
+
+	if (!zone || !new_rrs || !zone->names) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* the TTL of NSEC rrs should be set to the minimum TTL of
+	 * the zone SOA (RFC4035 Section 2.3)
+	 */
+	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
+
+	/* did the caller actually set it? if not,
+	 * fall back to default ttl
+	 */
+	if (soa && soa->rrs && soa->rrs->rr
+			&& ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
+		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
+	} else {
+		nsec_ttl = LDNS_DEFAULT_TTL;
+	}
+
+	if (zone->hashed_names) {
+		ldns_traverse_postorder(zone->hashed_names,
+				ldns_hashed_names_node_free, NULL);
+		LDNS_FREE(zone->hashed_names);
+	}
+	zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
+	if (zone->hashed_names && map) {
+		*map = zone->hashed_names;
+	}
+
+	first_name_node = ldns_dnssec_name_node_next_nonglue(
+					  ldns_rbtree_first(zone->names));
+
+	current_name_node = first_name_node;
+
+	while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
+			result == LDNS_STATUS_OK) {
+
+		current_name = (ldns_dnssec_name *) current_name_node->data;
+		nsec_rr = ldns_dnssec_create_nsec3(current_name,
+		                                   NULL,
+		                                   zone->soa->name,
+		                                   algorithm,
+		                                   flags,
+		                                   iterations,
+		                                   salt_length,
+		                                   salt);
+		/* by default, our nsec based generator adds rrsigs
+		 * remove the bitmap for empty nonterminals */
+		if (!current_name->rrsets) {
+			ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
+		}
+		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
+		result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
+		ldns_rr_list_push_rr(new_rrs, nsec_rr);
+		if (ldns_rr_owner(nsec_rr)) {
+			hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
+			if (hashmap_node == NULL) {
+				return LDNS_STATUS_MEM_ERR;
+			}
+			current_name->hashed_name = 
+				ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
+
+			if (current_name->hashed_name == NULL) {
+				LDNS_FREE(hashmap_node);
+				return LDNS_STATUS_MEM_ERR;
+			}
+			hashmap_node->key  = current_name->hashed_name;
+			hashmap_node->data = current_name;
+
+			if (! ldns_rbtree_insert(zone->hashed_names
+						, hashmap_node)) {
+				LDNS_FREE(hashmap_node);
+			}
+		}
+		current_name_node = ldns_dnssec_name_node_next_nonglue(
+		                   ldns_rbtree_next(current_name_node));
+	}
+	if (result != LDNS_STATUS_OK) {
+		return result;
+	}
+
+	/* Make sorted list of nsec3s (via zone->hashed_names)
+	 */
+	nsec3_list = ldns_rr_list_new();
+	if (nsec3_list == NULL) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	for ( hashmap_node  = ldns_rbtree_first(zone->hashed_names)
+	    ; hashmap_node != LDNS_RBTREE_NULL
+	    ; hashmap_node  = ldns_rbtree_next(hashmap_node)
+	    ) {
+		current_name = (ldns_dnssec_name *) hashmap_node->data;
+		nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
+		if (nsec_rr) {
+			ldns_rr_list_push_rr(nsec3_list, nsec_rr);
+		}
+	}
+	result = ldns_dnssec_chain_nsec3_list(nsec3_list);
+	ldns_rr_list_free(nsec3_list);
+
+	return result;
+}
+
+ldns_status
+ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
+		ldns_rr_list *new_rrs,
+		uint8_t algorithm,
+		uint8_t flags,
+		uint16_t iterations,
+		uint8_t salt_length,
+		uint8_t *salt)
+{
+	return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
+		       	flags, iterations, salt_length, salt, NULL);
+
+}
+#endif /* HAVE_SSL */
+
+ldns_dnssec_rrs *
+ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
+			     , ATTR_UNUSED(ldns_key_list *key_list)
+			     , int (*func)(ldns_rr *, void *)
+			     , void *arg
+			     )
+{
+	ldns_dnssec_rrs *base_rrs = signatures;
+	ldns_dnssec_rrs *cur_rr = base_rrs;
+	ldns_dnssec_rrs *prev_rr = NULL;
+	ldns_dnssec_rrs *next_rr;
+
+	uint16_t keytag;
+	size_t i;
+
+	if (!cur_rr) {
+		switch(func(NULL, arg)) {
+		case LDNS_SIGNATURE_LEAVE_ADD_NEW:
+		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
+		break;
+		case LDNS_SIGNATURE_LEAVE_NO_ADD:
+		case LDNS_SIGNATURE_REMOVE_NO_ADD:
+		ldns_key_list_set_use(key_list, false);
+		break;
+		default:
+#ifdef STDERR_MSGS
+			fprintf(stderr, "[XX] unknown return value from callback\n");
+#endif
+			break;
+		}
+		return NULL;
+	}
+	(void)func(cur_rr->rr, arg);
+
+	while (cur_rr) {
+		next_rr = cur_rr->next;
+
+		switch (func(cur_rr->rr, arg)) {
+		case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
+			prev_rr = cur_rr;
+			break;
+		case LDNS_SIGNATURE_LEAVE_NO_ADD:
+			keytag = ldns_rdf2native_int16(
+					   ldns_rr_rrsig_keytag(cur_rr->rr));
+			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
+				if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
+				    keytag) {
+					ldns_key_set_use(ldns_key_list_key(key_list, i),
+								  false);
+				}
+			}
+			prev_rr = cur_rr;
+			break;
+		case LDNS_SIGNATURE_REMOVE_NO_ADD:
+			keytag = ldns_rdf2native_int16(
+					   ldns_rr_rrsig_keytag(cur_rr->rr));
+			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
+				if (ldns_key_keytag(ldns_key_list_key(key_list, i))
+				    == keytag) {
+					ldns_key_set_use(ldns_key_list_key(key_list, i),
+								  false);
+				}
+			}
+			if (prev_rr) {
+				prev_rr->next = next_rr;
+			} else {
+				base_rrs = next_rr;
+			}
+			LDNS_FREE(cur_rr);
+			break;
+		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
+			if (prev_rr) {
+				prev_rr->next = next_rr;
+			} else {
+				base_rrs = next_rr;
+			}
+			LDNS_FREE(cur_rr);
+			break;
+		default:
+#ifdef STDERR_MSGS
+			fprintf(stderr, "[XX] unknown return value from callback\n");
+#endif
+			break;
+		}
+		cur_rr = next_rr;
+	}
+
+	return base_rrs;
+}
+
+#ifdef HAVE_SSL
+ldns_status
+ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
+                               ldns_rr_list *new_rrs,
+                               ldns_key_list *key_list,
+                               int (*func)(ldns_rr *, void*),
+                               void *arg)
+{
+	return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
+		func, arg, 0);
+}
+
+/** If there are KSKs use only them and mark ZSKs unused */
+static void
+ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
+{
+	int saw_ksk = 0;
+	size_t i;
+	for(i=0; i<ldns_key_list_key_count(key_list); i++)
+		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
+			saw_ksk = 1;
+			break;
+		}
+	if(!saw_ksk)
+		return;
+	for(i=0; i<ldns_key_list_key_count(key_list); i++)
+		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
+			ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
+}
+
+/** If there are no ZSKs use KSK as ZSK */
+static void
+ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
+{
+	int saw_zsk = 0;
+	size_t i;
+	for(i=0; i<ldns_key_list_key_count(key_list); i++)
+		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
+			saw_zsk = 1;
+			break;
+		}
+	if(!saw_zsk)
+		return;
+	/* else filter all KSKs */
+	for(i=0; i<ldns_key_list_key_count(key_list); i++)
+		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
+			ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
+}
+
+ldns_status
+ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
+				  , ldns_rr_list *new_rrs
+				  , ldns_key_list *key_list
+				  , int (*func)(ldns_rr *, void*)
+				  , void *arg
+				  , int flags
+				  )
+{
+	ldns_status result = LDNS_STATUS_OK;
+
+	ldns_rbnode_t *cur_node;
+	ldns_rr_list *rr_list;
+
+	ldns_dnssec_name *cur_name;
+	ldns_dnssec_rrsets *cur_rrset;
+	ldns_dnssec_rrs *cur_rr;
+
+	ldns_rr_list *siglist;
+
+	size_t i;
+
+	int on_delegation_point = 0; /* handle partially occluded names */
+
+	ldns_rr_list *pubkey_list = ldns_rr_list_new();
+	for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
+		ldns_rr_list_push_rr( pubkey_list
+				    , ldns_key2rr(ldns_key_list_key(
+							key_list, i))
+				    );
+	}
+	/* TODO: callback to see is list should be signed */
+	/* TODO: remove 'old' signatures from signature list */
+	cur_node = ldns_rbtree_first(zone->names);
+	while (cur_node != LDNS_RBTREE_NULL) {
+		cur_name = (ldns_dnssec_name *) cur_node->data;
+
+		if (!cur_name->is_glue) {
+			on_delegation_point = ldns_dnssec_rrsets_contains_type(
+					cur_name->rrsets, LDNS_RR_TYPE_NS)
+				&& !ldns_dnssec_rrsets_contains_type(
+					cur_name->rrsets, LDNS_RR_TYPE_SOA);
+			cur_rrset = cur_name->rrsets;
+			while (cur_rrset) {
+				/* reset keys to use */
+				ldns_key_list_set_use(key_list, true);
+
+				/* walk through old sigs, remove the old,
+				   and mark which keys (not) to use) */
+				cur_rrset->signatures =
+					ldns_dnssec_remove_signatures(cur_rrset->signatures,
+											key_list,
+											func,
+											arg);
+				if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
+					cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
+					ldns_key_list_filter_for_dnskey(key_list);
+
+				if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
+					ldns_key_list_filter_for_non_dnskey(key_list);
+
+				/* TODO: just set count to zero? */
+				rr_list = ldns_rr_list_new();
+
+				cur_rr = cur_rrset->rrs;
+				while (cur_rr) {
+					ldns_rr_list_push_rr(rr_list, cur_rr->rr);
+					cur_rr = cur_rr->next;
+				}
+
+				/* only sign non-delegation RRsets */
+				/* (glue should have been marked earlier, 
+				 *  except on the delegation points itself) */
+				if (!on_delegation_point ||
+						ldns_rr_list_type(rr_list) 
+							== LDNS_RR_TYPE_DS ||
+						ldns_rr_list_type(rr_list) 
+							== LDNS_RR_TYPE_NSEC ||
+						ldns_rr_list_type(rr_list) 
+							== LDNS_RR_TYPE_NSEC3) {
+					siglist = ldns_sign_public(rr_list, key_list);
+					for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
+						if (cur_rrset->signatures) {
+							result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
+											   ldns_rr_list_rr(siglist,
+														    i));
+						} else {
+							cur_rrset->signatures = ldns_dnssec_rrs_new();
+							cur_rrset->signatures->rr =
+								ldns_rr_list_rr(siglist, i);
+						}
+						if (new_rrs) {
+							ldns_rr_list_push_rr(new_rrs,
+												 ldns_rr_list_rr(siglist,
+															  i));
+						}
+					}
+					ldns_rr_list_free(siglist);
+				}
+
+				ldns_rr_list_free(rr_list);
+
+				cur_rrset = cur_rrset->next;
+			}
+
+			/* sign the nsec */
+			ldns_key_list_set_use(key_list, true);
+			cur_name->nsec_signatures =
+				ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
+										key_list,
+										func,
+										arg);
+			ldns_key_list_filter_for_non_dnskey(key_list);
+
+			rr_list = ldns_rr_list_new();
+			ldns_rr_list_push_rr(rr_list, cur_name->nsec);
+			siglist = ldns_sign_public(rr_list, key_list);
+
+			for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
+				if (cur_name->nsec_signatures) {
+					result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
+									   ldns_rr_list_rr(siglist, i));
+				} else {
+					cur_name->nsec_signatures = ldns_dnssec_rrs_new();
+					cur_name->nsec_signatures->rr =
+						ldns_rr_list_rr(siglist, i);
+				}
+				if (new_rrs) {
+					ldns_rr_list_push_rr(new_rrs,
+								 ldns_rr_list_rr(siglist, i));
+				}
+			}
+
+			ldns_rr_list_free(siglist);
+			ldns_rr_list_free(rr_list);
+		}
+		cur_node = ldns_rbtree_next(cur_node);
+	}
+
+	ldns_rr_list_deep_free(pubkey_list);
+	return result;
+}
+
+ldns_status
+ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
+				  ldns_rr_list *new_rrs,
+				  ldns_key_list *key_list,
+				  int (*func)(ldns_rr *, void *),
+				  void *arg)
+{
+	return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
+}
+
+ldns_status
+ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
+				  ldns_rr_list *new_rrs,
+				  ldns_key_list *key_list,
+				  int (*func)(ldns_rr *, void *),
+				  void *arg,
+				  int flags)
+{
+	ldns_status result = LDNS_STATUS_OK;
+
+	if (!zone || !new_rrs || !key_list) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* zone is already sorted */
+	result = ldns_dnssec_zone_mark_glue(zone);
+	if (result != LDNS_STATUS_OK) {
+		return result;
+	}
+
+	/* check whether we need to add nsecs */
+	if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
+		result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
+		if (result != LDNS_STATUS_OK) {
+			return result;
+		}
+	}
+
+	result = ldns_dnssec_zone_create_rrsigs_flg(zone,
+					new_rrs,
+					key_list,
+					func,
+					arg,
+					flags);
+
+	return result;
+}
+
+ldns_status
+ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
+					   ldns_rr_list *new_rrs,
+					   ldns_key_list *key_list,
+					   int (*func)(ldns_rr *, void *),
+					   void *arg,
+					   uint8_t algorithm,
+					   uint8_t flags,
+					   uint16_t iterations,
+					   uint8_t salt_length,
+					   uint8_t *salt)
+{
+	return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
+		func, arg, algorithm, flags, iterations, salt_length, salt, 0,
+	       	NULL);
+}
+
+ldns_status
+ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
+		ldns_rr_list *new_rrs,
+		ldns_key_list *key_list,
+		int (*func)(ldns_rr *, void *),
+		void *arg,
+		uint8_t algorithm,
+		uint8_t flags,
+		uint16_t iterations,
+		uint8_t salt_length,
+		uint8_t *salt,
+		int signflags,
+		ldns_rbtree_t **map)
+{
+	ldns_rr *nsec3, *nsec3param;
+	ldns_status result = LDNS_STATUS_OK;
+
+	/* zone is already sorted */
+	result = ldns_dnssec_zone_mark_glue(zone);
+	if (result != LDNS_STATUS_OK) {
+		return result;
+	}
+
+	/* TODO if there are already nsec3s presents and their
+	 * parameters are the same as these, we don't have to recreate
+	 */
+	if (zone->names) {
+		/* add empty nonterminals */
+		result = ldns_dnssec_zone_add_empty_nonterminals(zone);
+		if (result != LDNS_STATUS_OK) {
+			return result;
+		}
+
+		nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
+		if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
+			/* no need to recreate */
+		} else {
+			if (!ldns_dnssec_zone_find_rrset(zone,
+									   zone->soa->name,
+									   LDNS_RR_TYPE_NSEC3PARAM)) {
+				/* create and add the nsec3param rr */
+				nsec3param =
+					ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
+				ldns_rr_set_owner(nsec3param,
+							   ldns_rdf_clone(zone->soa->name));
+				ldns_nsec3_add_param_rdfs(nsec3param,
+									 algorithm,
+									 flags,
+									 iterations,
+									 salt_length,
+									 salt);
+				/* always set bit 7 of the flags to zero, according to
+				 * rfc5155 section 11. The bits are counted from right to left,
+				 * so bit 7 in rfc5155 is bit 0 in ldns */
+				ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
+				result = ldns_dnssec_zone_add_rr(zone, nsec3param);
+				if (result != LDNS_STATUS_OK) {
+					return result;
+				}
+				ldns_rr_list_push_rr(new_rrs, nsec3param);
+			}
+			result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
+											new_rrs,
+											algorithm,
+											flags,
+											iterations,
+											salt_length,
+											salt,
+											map);
+			if (result != LDNS_STATUS_OK) {
+				return result;
+			}
+		}
+
+		result = ldns_dnssec_zone_create_rrsigs_flg(zone,
+						new_rrs,
+						key_list,
+						func,
+						arg,
+						signflags);
+	}
+
+	return result;
+}
+
+ldns_status
+ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
+		ldns_rr_list *new_rrs,
+		ldns_key_list *key_list,
+		int (*func)(ldns_rr *, void *),
+		void *arg,
+		uint8_t algorithm,
+		uint8_t flags,
+		uint16_t iterations,
+		uint8_t salt_length,
+		uint8_t *salt,
+		int signflags)
+{
+	return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
+		func, arg, algorithm, flags, iterations, salt_length, salt,
+		signflags, NULL);
+}
+
+ldns_zone *
+ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
+{
+	ldns_dnssec_zone *dnssec_zone;
+	ldns_zone *signed_zone;
+	ldns_rr_list *new_rrs;
+	size_t i;
+
+	signed_zone = ldns_zone_new();
+	dnssec_zone = ldns_dnssec_zone_new();
+
+	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
+	ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
+
+	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
+		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
+								 ldns_rr_list_rr(ldns_zone_rrs(zone),
+											  i));
+		ldns_zone_push_rr(signed_zone,
+					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
+											   i)));
+	}
+
+	new_rrs = ldns_rr_list_new();
+	(void) ldns_dnssec_zone_sign(dnssec_zone,
+						    new_rrs,
+						    key_list,
+						    ldns_dnssec_default_replace_signatures,
+						    NULL);
+
+    	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
+		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
+						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
+	}
+
+	ldns_rr_list_deep_free(new_rrs);
+	ldns_dnssec_zone_free(dnssec_zone);
+
+	return signed_zone;
+}
+
+ldns_zone *
+ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt)
+{
+	ldns_dnssec_zone *dnssec_zone;
+	ldns_zone *signed_zone;
+	ldns_rr_list *new_rrs;
+	size_t i;
+
+	signed_zone = ldns_zone_new();
+	dnssec_zone = ldns_dnssec_zone_new();
+
+	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
+	ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
+
+	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
+		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
+								 ldns_rr_list_rr(ldns_zone_rrs(zone),
+											  i));
+		ldns_zone_push_rr(signed_zone, 
+					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
+											   i)));
+	}
+
+	new_rrs = ldns_rr_list_new();
+	(void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
+								new_rrs,
+								key_list,
+								ldns_dnssec_default_replace_signatures,
+								NULL,
+								algorithm,
+								flags,
+								iterations,
+								salt_length,
+								salt);
+
+    	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
+		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
+						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
+	}
+
+	ldns_rr_list_deep_free(new_rrs);
+	ldns_dnssec_zone_free(dnssec_zone);
+
+	return signed_zone;
+}
+#endif /* HAVE_SSL */
+
+
diff --git a/ldns/src/dnssec_verify.c b/ldns/src/dnssec_verify.c
new file mode 100644
index 0000000..1af6635
--- /dev/null
+++ b/ldns/src/dnssec_verify.c
@@ -0,0 +1,2684 @@
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <strings.h>
+#include <time.h>
+
+#ifdef HAVE_SSL
+/* this entire file is rather useless when you don't have
+ * crypto...
+ */
+#include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/md5.h>
+
+ldns_dnssec_data_chain *
+ldns_dnssec_data_chain_new(void)
+{
+	ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
+        if(!nc) return NULL;
+	/* 
+	 * not needed anymore because CALLOC initalizes everything to zero.
+
+	nc->rrset = NULL;
+	nc->parent_type = 0;
+	nc->parent = NULL;
+	nc->signatures = NULL;
+	nc->packet_rcode = 0;
+	nc->packet_qtype = 0;
+	nc->packet_nodata = false;
+
+	 */
+	return nc;
+}
+
+void
+ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
+{
+	LDNS_FREE(chain);
+}
+
+void
+ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
+{
+	ldns_rr_list_deep_free(chain->rrset);
+	ldns_rr_list_deep_free(chain->signatures);
+	if (chain->parent) {
+		ldns_dnssec_data_chain_deep_free(chain->parent);
+	}
+	LDNS_FREE(chain);
+}
+
+void
+ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt,
+		const ldns_dnssec_data_chain *chain)
+{
+	ldns_lookup_table *rcode;
+	const ldns_rr_descriptor *rr_descriptor;
+	if (chain) {
+		ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
+		if (ldns_rr_list_rr_count(chain->rrset) > 0) {
+			rcode = ldns_lookup_by_id(ldns_rcodes,
+								 (int) chain->packet_rcode);
+			if (rcode) {
+				fprintf(out, ";; rcode: %s\n", rcode->name);
+			}
+
+			rr_descriptor = ldns_rr_descript(chain->packet_qtype);
+			if (rr_descriptor && rr_descriptor->_name) {
+				fprintf(out, ";; qtype: %s\n", rr_descriptor->_name);
+			} else if (chain->packet_qtype != 0) {
+				fprintf(out, "TYPE%u", 
+					   chain->packet_qtype);
+			}
+			if (chain->packet_nodata) {
+				fprintf(out, ";; NODATA response\n");
+			}
+			fprintf(out, "rrset:\n");
+			ldns_rr_list_print_fmt(out, fmt, chain->rrset);
+			fprintf(out, "sigs:\n");
+			ldns_rr_list_print_fmt(out, fmt, chain->signatures);
+			fprintf(out, "---\n");
+		} else {
+			fprintf(out, "<no data>\n");
+		}
+	}
+}
+void
+ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
+{
+	ldns_dnssec_data_chain_print_fmt(
+			out, ldns_output_format_default, chain);
+}
+
+
+static void
+ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
+					    uint16_t qflags,
+					    const ldns_pkt *pkt,
+					    ldns_rr_list *signatures,
+						ldns_dnssec_data_chain *new_chain,
+						ldns_rdf *key_name,
+						ldns_rr_class c) {
+	ldns_rr_list *keys;
+	ldns_pkt *my_pkt;
+	if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
+		new_chain->signatures = ldns_rr_list_clone(signatures);
+		new_chain->parent_type = 0;
+
+		keys = ldns_pkt_rr_list_by_name_and_type(
+				  pkt,
+				 key_name,
+				 LDNS_RR_TYPE_DNSKEY,
+				 LDNS_SECTION_ANY_NOQUESTION
+			  );
+		if (!keys) {
+			my_pkt = ldns_resolver_query(res,
+									key_name,
+									LDNS_RR_TYPE_DNSKEY,
+									c,
+									qflags);
+			if (my_pkt) {
+			keys = ldns_pkt_rr_list_by_name_and_type(
+					  my_pkt,
+					 key_name,
+					 LDNS_RR_TYPE_DNSKEY,
+					 LDNS_SECTION_ANY_NOQUESTION
+				  );
+			new_chain->parent = ldns_dnssec_build_data_chain(res,
+													qflags,
+													keys,
+													my_pkt,
+													NULL);
+			new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
+			ldns_pkt_free(my_pkt);
+			}
+		} else {
+			new_chain->parent = ldns_dnssec_build_data_chain(res,
+													qflags,
+													keys,
+													pkt,
+													NULL);
+			new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
+		}
+		ldns_rr_list_deep_free(keys);
+	}
+}
+
+static void
+ldns_dnssec_build_data_chain_other(ldns_resolver *res,
+					    uint16_t qflags,
+						ldns_dnssec_data_chain *new_chain,
+						ldns_rdf *key_name,
+						ldns_rr_class c,
+						ldns_rr_list *dss)
+{
+	/* 'self-signed', parent is a DS */
+	
+	/* okay, either we have other keys signing the current one,
+	 * or the current
+	 * one should have a DS record in the parent zone.
+	 * How do we find this out? Try both?
+	 *
+	 * request DNSKEYS for current zone,
+	 * add all signatures to current level
+	 */
+	ldns_pkt *my_pkt;
+	ldns_rr_list *signatures2;
+	
+	new_chain->parent_type = 1;
+
+	my_pkt = ldns_resolver_query(res,
+							key_name,
+							LDNS_RR_TYPE_DS,
+							c,
+							qflags);
+	if (my_pkt) {
+	dss = ldns_pkt_rr_list_by_name_and_type(my_pkt,
+									key_name,
+									LDNS_RR_TYPE_DS,
+									LDNS_SECTION_ANY_NOQUESTION
+									);
+	if (dss) {
+		new_chain->parent = ldns_dnssec_build_data_chain(res,
+												qflags,
+												dss,
+												my_pkt,
+												NULL);
+		new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
+		ldns_rr_list_deep_free(dss);
+	}
+	ldns_pkt_free(my_pkt);
+	}
+
+	my_pkt = ldns_resolver_query(res,
+							key_name,
+							LDNS_RR_TYPE_DNSKEY,
+							c,
+							qflags);
+	if (my_pkt) {
+	signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
+										   key_name,
+										   LDNS_RR_TYPE_RRSIG,
+										   LDNS_SECTION_ANSWER);
+	if (signatures2) {
+		if (new_chain->signatures) {
+			printf("There were already sigs!\n");
+			ldns_rr_list_deep_free(new_chain->signatures);
+			printf("replacing the old sigs\n");
+		}
+		new_chain->signatures = signatures2;
+	}
+	ldns_pkt_free(my_pkt);
+	}
+}
+
+static ldns_dnssec_data_chain *
+ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
+                                       uint16_t qflags,
+                                       ldns_rr *orig_rr,
+                                       const ldns_rr_list *rrset,
+                                       ldns_dnssec_data_chain *new_chain)
+{
+	ldns_rdf *possible_parent_name;
+	ldns_pkt *my_pkt;
+	/* apparently we were not able to find a signing key, so
+	   we assume the chain ends here
+	*/
+	/* try parents for auth denial of DS */
+	if (orig_rr) {
+		possible_parent_name = ldns_rr_owner(orig_rr);
+	} else if (rrset && ldns_rr_list_rr_count(rrset) > 0) {
+		possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0));
+	} else {
+		/* no information to go on, give up */
+		return new_chain;
+	}
+
+	my_pkt = ldns_resolver_query(res,
+	              possible_parent_name,
+	              LDNS_RR_TYPE_DS,
+	              LDNS_RR_CLASS_IN,
+	              qflags);
+	if (!my_pkt) {
+		return new_chain;
+	}
+
+	if (ldns_pkt_ancount(my_pkt) > 0) {
+		/* add error, no sigs but DS in parent */
+		/*ldns_pkt_print(stdout, my_pkt);*/
+		ldns_pkt_free(my_pkt);
+	} else {
+		/* are there signatures? */
+		new_chain->parent =  ldns_dnssec_build_data_chain(res, 
+		                          qflags, 
+		                          NULL,
+		                          my_pkt,
+		                          NULL);
+
+		new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
+		
+	}
+	return new_chain;
+}
+
+
+ldns_dnssec_data_chain *
+ldns_dnssec_build_data_chain(ldns_resolver *res,
+					    uint16_t qflags,
+					    const ldns_rr_list *rrset,
+					    const ldns_pkt *pkt,
+					    ldns_rr *orig_rr)
+{
+	ldns_rr_list *signatures = NULL;
+	ldns_rr_list *dss = NULL;
+	
+	ldns_rr_list *my_rrset;
+
+	ldns_pkt *my_pkt;
+
+	ldns_rdf *name = NULL, *key_name = NULL;
+	ldns_rr_type type = 0;
+	ldns_rr_class c = 0;
+
+	bool other_rrset = false;
+
+	ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
+
+	assert(pkt != NULL);
+
+	if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
+		/* hmm. no dnssec data in the packet. go up to try and deny
+		 * DS? */
+		return new_chain;
+	}
+
+	if (orig_rr) {
+		new_chain->rrset = ldns_rr_list_new();
+		ldns_rr_list_push_rr(new_chain->rrset, orig_rr);
+		new_chain->parent = ldns_dnssec_build_data_chain(res,
+											    qflags,
+											    rrset,
+											    pkt,
+											    NULL);
+		new_chain->packet_rcode = ldns_pkt_get_rcode(pkt);
+		new_chain->packet_qtype = ldns_rr_get_type(orig_rr);
+		if (ldns_pkt_ancount(pkt) == 0) {
+			new_chain->packet_nodata = true;
+		}
+		return new_chain;
+	}
+	
+	if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
+		/* hmm, no data, do we have denial? only works if pkt was given,
+		   otherwise caller has to do the check himself */
+		new_chain->packet_nodata = true;
+		if (pkt) {
+			my_rrset = ldns_pkt_rr_list_by_type(pkt,
+										 LDNS_RR_TYPE_NSEC,
+										 LDNS_SECTION_ANY_NOQUESTION
+										 );
+			if (my_rrset) {
+				if (ldns_rr_list_rr_count(my_rrset) > 0) {
+					type = LDNS_RR_TYPE_NSEC;
+					other_rrset = true;
+				} else {
+					ldns_rr_list_deep_free(my_rrset);
+					my_rrset = NULL;
+				}
+			} else {
+				/* nothing, try nsec3 */
+				my_rrset = ldns_pkt_rr_list_by_type(pkt,
+						     LDNS_RR_TYPE_NSEC3,
+							LDNS_SECTION_ANY_NOQUESTION);
+				if (my_rrset) {
+					if (ldns_rr_list_rr_count(my_rrset) > 0) {
+						type = LDNS_RR_TYPE_NSEC3;
+						other_rrset = true;
+					} else {
+						ldns_rr_list_deep_free(my_rrset);
+						my_rrset = NULL;
+					}
+				} else {
+					/* nothing, stop */
+					/* try parent zone? for denied insecure? */
+					return new_chain;
+				}
+			}
+		} else {
+			return new_chain;
+		}
+	} else {
+		my_rrset = (ldns_rr_list *) rrset;
+	}
+	
+	if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) {
+		new_chain->rrset = ldns_rr_list_clone(my_rrset);
+		name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0));
+		type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0));
+		c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0));
+	}
+	
+	if (other_rrset) {
+		ldns_rr_list_deep_free(my_rrset);
+	}
+	
+	/* normally there will only be 1 signature 'set'
+	   but there can be more than 1 denial (wildcards)
+	   so check for NSEC
+	*/
+	if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) {
+		/* just throw in all signatures, the tree builder must sort
+		   this out */
+		if (pkt) {
+			signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
+		} else {
+			my_pkt = ldns_resolver_query(res, name, type, c, qflags);
+			if (my_pkt) {
+			signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
+			ldns_pkt_free(my_pkt);
+			}
+		}
+	} else {
+		if (pkt) {
+			signatures =
+				ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt,
+													name,
+													type);
+		}
+		if (!signatures) {
+			my_pkt = ldns_resolver_query(res, name, type, c, qflags);
+			if (my_pkt) {
+			signatures =
+				ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt,
+													name,
+													type);
+			ldns_pkt_free(my_pkt);
+			}
+		}
+	}
+
+	if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
+		key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
+	}
+	if (!key_name) {
+		if (signatures) {
+			ldns_rr_list_deep_free(signatures);
+		}
+		return ldns_dnssec_build_data_chain_nokeyname(res,
+		                                              qflags,
+		                                              orig_rr,
+		                                              rrset,
+		                                              new_chain);
+	}
+	if (type != LDNS_RR_TYPE_DNSKEY) {
+		ldns_dnssec_build_data_chain_dnskey(res,
+		                                    qflags,
+		                                    pkt,
+		                                    signatures,
+		                                    new_chain,
+		                                    key_name,
+		                                    c
+		                                   );
+	} else {
+		ldns_dnssec_build_data_chain_other(res,
+		                                   qflags,
+		                                   new_chain,
+		                                   key_name,
+		                                   c,
+		                                   dss
+		                                  );
+	}
+	if (signatures) {
+		ldns_rr_list_deep_free(signatures);
+	}
+	return new_chain;
+}
+
+ldns_dnssec_trust_tree *
+ldns_dnssec_trust_tree_new(void)
+{
+	ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
+										   1);
+        if(!new_tree) return NULL;
+	new_tree->rr = NULL;
+	new_tree->rrset = NULL;
+	new_tree->parent_count = 0;
+
+	return new_tree;
+}
+
+void
+ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
+{
+	size_t i;
+	if (tree) {
+		for (i = 0; i < tree->parent_count; i++) {
+			ldns_dnssec_trust_tree_free(tree->parents[i]);
+		}
+	}
+	LDNS_FREE(tree);
+}
+
+size_t
+ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
+{
+	size_t result = 0;
+	size_t parent = 0;
+	size_t i;
+	
+	for (i = 0; i < tree->parent_count; i++) {
+		parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
+		if (parent > result) {
+			result = parent;
+		}
+	}
+	return 1 + result;
+}
+
+/* TODO ldns_ */
+static void
+print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
+{
+	size_t i;
+	for (i = 0; i < nr; i++) {
+		if (i == nr - 1) {
+			fprintf(out, "|---");
+		} else if (map && i < treedepth && map[i] == 1) {
+			fprintf(out, "|   ");
+		} else {
+			fprintf(out, "    ");
+		}
+	}
+}
+
+static void
+ldns_dnssec_trust_tree_print_sm_fmt(FILE *out, 
+		const ldns_output_format *fmt,
+		ldns_dnssec_trust_tree *tree,
+		size_t tabs,
+		bool extended,
+		uint8_t *sibmap,
+		size_t treedepth)
+{
+	size_t i;
+	const ldns_rr_descriptor *descriptor;
+	bool mapset = false;
+	
+	if (!sibmap) {
+		treedepth = ldns_dnssec_trust_tree_depth(tree);
+		sibmap = LDNS_XMALLOC(uint8_t, treedepth);
+                if(!sibmap)
+                        return; /* mem err */
+		memset(sibmap, 0, treedepth);
+		mapset = true;
+	}
+	
+	if (tree) {
+		if (tree->rr) {
+			print_tabs(out, tabs, sibmap, treedepth);
+			ldns_rdf_print(out, ldns_rr_owner(tree->rr));
+			descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
+
+			if (descriptor->_name) {
+				fprintf(out, " (%s", descriptor->_name);
+			} else {
+				fprintf(out, " (TYPE%d", 
+					   ldns_rr_get_type(tree->rr));
+			}
+			if (tabs > 0) {
+				if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
+					fprintf(out, " keytag: %u",
+					        (unsigned int) ldns_calc_keytag(tree->rr));
+					fprintf(out, " alg: ");
+					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
+					fprintf(out, " flags: ");
+					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
+				} else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
+					fprintf(out, " keytag: ");
+					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
+					fprintf(out, " digest type: ");
+					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
+				}
+				if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
+					fprintf(out, " ");
+					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
+					fprintf(out, " ");
+					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
+				}
+			}
+			
+			fprintf(out, ")\n");
+			for (i = 0; i < tree->parent_count; i++) {
+				if (tree->parent_count > 1 && i < tree->parent_count - 1) {
+					sibmap[tabs] = 1;
+				} else {
+					sibmap[tabs] = 0;
+				}
+				/* only print errors */
+				if (ldns_rr_get_type(tree->parents[i]->rr) == 
+				    LDNS_RR_TYPE_NSEC ||
+				    ldns_rr_get_type(tree->parents[i]->rr) ==
+				    LDNS_RR_TYPE_NSEC3) {
+					if (tree->parent_status[i] == LDNS_STATUS_OK) {
+						print_tabs(out, tabs + 1, sibmap, treedepth);
+						if (tabs == 0 &&
+						    ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
+							ldns_rr_rd_count(tree->rr) > 0) {
+							fprintf(out, "Existence of DS is denied by:\n");
+						} else {
+							fprintf(out, "Existence is denied by:\n");
+						}
+					} else {
+						/* NS records aren't signed */
+						if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
+							fprintf(out, "Existence of DS is denied by:\n");
+						} else {
+							print_tabs(out, tabs + 1, sibmap, treedepth);
+							fprintf(out,
+								   "Error in denial of existence: %s\n",
+								   ldns_get_errorstr_by_id(
+									   tree->parent_status[i]));
+						}
+					}
+				} else
+					if (tree->parent_status[i] != LDNS_STATUS_OK) {
+						print_tabs(out, tabs + 1, sibmap, treedepth);
+						fprintf(out,
+							   "%s:\n",
+							   ldns_get_errorstr_by_id(
+							       tree->parent_status[i]));
+						if (tree->parent_status[i]
+						    == LDNS_STATUS_SSL_ERR) {
+							printf("; SSL Error: ");
+							ERR_load_crypto_strings();
+							ERR_print_errors_fp(stdout);
+							printf("\n");
+						}
+						ldns_rr_print_fmt(out, fmt, 
+							tree->
+							parent_signature[i]);
+						printf("For RRset:\n");
+						ldns_rr_list_print_fmt(out, fmt,
+								tree->rrset);
+						printf("With key:\n");
+						ldns_rr_print_fmt(out, fmt,
+							tree->parents[i]->rr);
+					}
+				ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
+						tree->parents[i],
+						tabs+1,
+						extended,
+						sibmap,
+						treedepth);
+			}
+		} else {
+			print_tabs(out, tabs, sibmap, treedepth);
+			fprintf(out, "<no data>\n");
+		}
+	} else {
+		fprintf(out, "<null pointer>\n");
+	}
+	
+	if (mapset) {
+		LDNS_FREE(sibmap);
+	}
+}
+
+void
+ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
+		ldns_dnssec_trust_tree *tree,
+		size_t tabs,
+		bool extended)
+{
+	ldns_dnssec_trust_tree_print_sm_fmt(out, fmt, 
+			tree, tabs, extended, NULL, 0);
+}
+
+void
+ldns_dnssec_trust_tree_print(FILE *out,
+		ldns_dnssec_trust_tree *tree,
+		size_t tabs,
+		bool extended)
+{
+	ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default, 
+			tree, tabs, extended);
+}
+
+
+ldns_status
+ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
+                                  const ldns_dnssec_trust_tree *parent,
+                                  const ldns_rr *signature,
+                                  const ldns_status parent_status)
+{
+	if (tree
+	    && parent
+	    && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
+		/*
+		  printf("Add parent for: ");
+		  ldns_rr_print(stdout, tree->rr);
+		  printf("parent: ");
+		  ldns_rr_print(stdout, parent->rr);
+		*/
+		tree->parents[tree->parent_count] =
+			(ldns_dnssec_trust_tree *) parent;
+		tree->parent_status[tree->parent_count] = parent_status;
+		tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
+		tree->parent_count++;
+		return LDNS_STATUS_OK;
+	} else {
+		return LDNS_STATUS_ERR;
+	}
+}
+
+/* if rr is null, take the first from the rrset */
+ldns_dnssec_trust_tree *
+ldns_dnssec_derive_trust_tree_time(
+		ldns_dnssec_data_chain *data_chain, 
+		ldns_rr *rr, 
+		time_t check_time
+		)
+{
+	ldns_rr_list *cur_rrset;
+	ldns_rr_list *cur_sigs;
+	ldns_rr *cur_rr = NULL;
+	ldns_rr *cur_sig_rr;
+	size_t i, j;
+
+	ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
+        if(!new_tree)
+                return NULL;
+	
+	if (data_chain && data_chain->rrset) {
+		cur_rrset = data_chain->rrset;
+	
+		cur_sigs = data_chain->signatures;
+
+		if (rr) {
+			cur_rr = rr;
+		}
+
+		if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
+			cur_rr = ldns_rr_list_rr(cur_rrset, 0);
+		}
+
+		if (cur_rr) {
+			new_tree->rr = cur_rr;
+			new_tree->rrset = cur_rrset;
+			/* there are three possibilities:
+			   1 - 'normal' rrset, signed by a key
+			   2 - dnskey signed by other dnskey
+			   3 - dnskey proven by higher level DS
+			   (data denied by nsec is a special case that can
+			   occur in multiple places)
+				   
+			*/
+			if (cur_sigs) {
+				for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
+					/* find the appropriate key in the parent list */
+					cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
+
+					if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
+						if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
+										   ldns_rr_owner(cur_rr)))
+							{
+								/* find first that does match */
+
+								for (j = 0;
+								     j < ldns_rr_list_rr_count(cur_rrset) && 
+										ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
+								     j++) {
+									cur_rr = ldns_rr_list_rr(cur_rrset, j);
+									
+								}
+								if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr), 
+												   ldns_rr_owner(cur_rr)))
+									{
+										break;
+									}
+							}
+							
+					}
+					/* option 1 */
+					if (data_chain->parent) {
+						ldns_dnssec_derive_trust_tree_normal_rrset_time(
+						    new_tree,
+						    data_chain,
+						    cur_sig_rr,
+						    check_time);
+					}
+
+					/* option 2 */
+					ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
+					    new_tree,
+					    data_chain,
+					    cur_rr,
+					    cur_sig_rr,
+					    check_time);
+				}
+					
+				ldns_dnssec_derive_trust_tree_ds_rrset_time(
+						new_tree, data_chain, 
+						cur_rr, check_time);
+			} else {
+				/* no signatures? maybe it's nsec data */
+					
+				/* just add every rr from parent as new parent */
+				ldns_dnssec_derive_trust_tree_no_sig_time(
+					new_tree, data_chain, check_time);
+			}
+		}
+	}
+
+	return new_tree;
+}
+
+ldns_dnssec_trust_tree *
+ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
+{
+	return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
+}
+
+void
+ldns_dnssec_derive_trust_tree_normal_rrset_time(
+		ldns_dnssec_trust_tree *new_tree, 
+		ldns_dnssec_data_chain *data_chain, 
+		ldns_rr *cur_sig_rr,
+		time_t check_time)
+{
+	size_t i, j;
+	ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset); 
+	ldns_dnssec_trust_tree *cur_parent_tree;
+	ldns_rr *cur_parent_rr;
+	uint16_t cur_keytag;
+	ldns_rr_list *tmp_rrset = NULL;
+	ldns_status cur_status;
+
+	cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
+	
+	for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
+		cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
+		if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
+			if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
+
+				/* TODO: check wildcard nsec too */
+				if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
+					tmp_rrset = cur_rrset;
+					if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
+					    == LDNS_RR_TYPE_NSEC ||
+					    ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
+					    == LDNS_RR_TYPE_NSEC3) {
+						/* might contain different names! 
+						   sort and split */
+						ldns_rr_list_sort(cur_rrset);
+						assert(tmp_rrset == cur_rrset);
+						tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
+						
+						/* with nsecs, this might be the wrong one */
+						while (tmp_rrset &&
+						       ldns_rr_list_rr_count(cur_rrset) > 0 &&
+						       ldns_dname_compare(
+								ldns_rr_owner(ldns_rr_list_rr(
+										        tmp_rrset, 0)),
+								ldns_rr_owner(cur_sig_rr)) != 0) {
+							ldns_rr_list_deep_free(tmp_rrset);
+							tmp_rrset =
+								ldns_rr_list_pop_rrset(cur_rrset);
+						}
+					}
+					cur_status = ldns_verify_rrsig_time(
+							tmp_rrset, 
+							cur_sig_rr, 
+							cur_parent_rr,
+							check_time);
+					if (tmp_rrset && tmp_rrset != cur_rrset
+							) {
+						ldns_rr_list_deep_free(
+								tmp_rrset);
+						tmp_rrset = NULL;
+					}
+					/* avoid dupes */
+					for (i = 0; i < new_tree->parent_count; i++) {
+						if (cur_parent_rr == new_tree->parents[i]->rr) {
+							goto done;
+						}
+					}
+
+					cur_parent_tree =
+						ldns_dnssec_derive_trust_tree_time(
+								data_chain->parent,
+						                cur_parent_rr,
+								check_time);
+					(void)ldns_dnssec_trust_tree_add_parent(new_tree,
+					           cur_parent_tree,
+					           cur_sig_rr,
+					           cur_status);
+				}
+			}
+		}
+	}
+ done:
+	ldns_rr_list_deep_free(cur_rrset);
+}
+
+void
+ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
+                                           ldns_dnssec_data_chain *data_chain,
+                                           ldns_rr *cur_sig_rr)
+{
+	ldns_dnssec_derive_trust_tree_normal_rrset_time(
+			new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
+}
+
+void
+ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
+		ldns_dnssec_trust_tree *new_tree, 
+		ldns_dnssec_data_chain *data_chain, 
+		ldns_rr *cur_rr, 
+		ldns_rr *cur_sig_rr,
+		time_t check_time)
+{
+	size_t j;
+	ldns_rr_list *cur_rrset = data_chain->rrset;
+	ldns_dnssec_trust_tree *cur_parent_tree;
+	ldns_rr *cur_parent_rr;
+	uint16_t cur_keytag;
+	ldns_status cur_status;
+
+	cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
+
+	for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
+		cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
+		if (cur_parent_rr != cur_rr &&
+		    ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
+			if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
+			    ) {
+				cur_parent_tree = ldns_dnssec_trust_tree_new();
+				cur_parent_tree->rr = cur_parent_rr;
+				cur_parent_tree->rrset = cur_rrset;
+				cur_status = ldns_verify_rrsig_time(
+						cur_rrset, cur_sig_rr, 
+						cur_parent_rr, check_time);
+				(void) ldns_dnssec_trust_tree_add_parent(new_tree,
+				            cur_parent_tree, cur_sig_rr, cur_status);
+			}
+		}
+	}
+}
+
+void
+ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
+                                           ldns_dnssec_data_chain *data_chain,
+                                           ldns_rr *cur_rr,
+                                           ldns_rr *cur_sig_rr)
+{
+	ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
+			new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
+}
+
+void
+ldns_dnssec_derive_trust_tree_ds_rrset_time(
+		ldns_dnssec_trust_tree *new_tree,
+		ldns_dnssec_data_chain *data_chain, 
+		ldns_rr *cur_rr,
+		time_t check_time)
+{
+	size_t j, h;
+	ldns_rr_list *cur_rrset = data_chain->rrset;
+	ldns_dnssec_trust_tree *cur_parent_tree;
+	ldns_rr *cur_parent_rr;
+
+	/* try the parent to see whether there are DSs there */
+	if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
+	    data_chain->parent &&
+	    data_chain->parent->rrset
+	    ) {
+		for (j = 0;
+			j < ldns_rr_list_rr_count(data_chain->parent->rrset);
+			j++) {
+			cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
+			if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
+				for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
+					cur_rr = ldns_rr_list_rr(cur_rrset, h);
+					if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
+						cur_parent_tree =
+							ldns_dnssec_derive_trust_tree_time(
+							    data_chain->parent, 
+							    cur_parent_rr,
+							    check_time);
+						(void) ldns_dnssec_trust_tree_add_parent(
+						            new_tree,
+						            cur_parent_tree,
+						            NULL,
+						            LDNS_STATUS_OK);
+					} else {
+						/*ldns_rr_print(stdout, cur_parent_rr);*/
+					}
+				}
+			}
+		}
+	}
+}
+
+void
+ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
+                                       ldns_dnssec_data_chain *data_chain,
+                                       ldns_rr *cur_rr)
+{
+	ldns_dnssec_derive_trust_tree_ds_rrset_time(
+			new_tree, data_chain, cur_rr, ldns_time(NULL));
+}
+
+void
+ldns_dnssec_derive_trust_tree_no_sig_time(
+		ldns_dnssec_trust_tree *new_tree, 
+		ldns_dnssec_data_chain *data_chain,
+		time_t check_time)
+{
+	size_t i;
+	ldns_rr_list *cur_rrset;
+	ldns_rr *cur_parent_rr;
+	ldns_dnssec_trust_tree *cur_parent_tree;
+	ldns_status result;
+	
+	if (data_chain->parent && data_chain->parent->rrset) {
+		cur_rrset = data_chain->parent->rrset;
+		/* nsec? */
+		if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
+			if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
+			    LDNS_RR_TYPE_NSEC3) {
+				result = ldns_dnssec_verify_denial_nsec3(
+					        new_tree->rr,
+						   cur_rrset,
+						   data_chain->parent->signatures,
+						   data_chain->packet_rcode,
+						   data_chain->packet_qtype,
+						   data_chain->packet_nodata);
+			} else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
+					 LDNS_RR_TYPE_NSEC) {
+				result = ldns_dnssec_verify_denial(
+					        new_tree->rr,
+						   cur_rrset,
+						   data_chain->parent->signatures);
+			} else {
+				/* unsigned zone, unsigned parent */
+				result = LDNS_STATUS_OK;
+			}
+		} else {
+			result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+		}
+		for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
+			cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
+			cur_parent_tree = 
+				ldns_dnssec_derive_trust_tree_time(
+						data_chain->parent, 
+						cur_parent_rr,
+						check_time);
+			(void) ldns_dnssec_trust_tree_add_parent(new_tree,
+			            cur_parent_tree, NULL, result);
+		}
+	}
+}
+
+void
+ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
+                                     ldns_dnssec_data_chain *data_chain)
+{
+	ldns_dnssec_derive_trust_tree_no_sig_time(
+			new_tree, data_chain, ldns_time(NULL));
+}
+
+/*
+ * returns OK if there is a path from tree to key with only OK
+ * the (first) error in between otherwise
+ * or NOT_FOUND if the key wasn't present at all
+ */
+ldns_status
+ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
+							  ldns_rr_list *trusted_keys)
+{
+	size_t i;
+	ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
+	bool equal;
+	ldns_status parent_result;
+	
+	if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
+		{ if (tree->rr) {
+				for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
+					equal = ldns_rr_compare_ds(
+							  tree->rr,
+							  ldns_rr_list_rr(trusted_keys, i));
+					if (equal) {
+						result = LDNS_STATUS_OK;
+						return result;
+					}
+				}
+			}
+			for (i = 0; i < tree->parent_count; i++) {
+				parent_result =
+					ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
+												  trusted_keys);
+				if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
+					if (tree->parent_status[i] != LDNS_STATUS_OK) {
+						result = tree->parent_status[i];
+					} else {
+						if (tree->rr &&
+						    ldns_rr_get_type(tree->rr)
+						    == LDNS_RR_TYPE_NSEC &&
+						    parent_result == LDNS_STATUS_OK
+						    ) {
+							result =
+								LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
+						} else {
+							result = parent_result;
+						}
+					}
+				}
+			}
+		} else {
+		result = LDNS_STATUS_ERR;
+	}
+	
+	return result;
+}
+
+ldns_status
+ldns_verify_time(
+		ldns_rr_list *rrset,
+		ldns_rr_list *rrsig, 
+		const ldns_rr_list *keys, 
+		time_t check_time,
+		ldns_rr_list *good_keys
+		)
+{
+	uint16_t i;
+	ldns_status verify_result = LDNS_STATUS_ERR;
+
+	if (!rrset || !rrsig || !keys) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (ldns_rr_list_rr_count(rrset) < 1) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (ldns_rr_list_rr_count(rrsig) < 1) {
+		return LDNS_STATUS_CRYPTO_NO_RRSIG;
+	}
+	
+	if (ldns_rr_list_rr_count(keys) < 1) {
+		verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
+	} else {
+		for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
+			ldns_status s = ldns_verify_rrsig_keylist_time(
+					rrset, ldns_rr_list_rr(rrsig, i), 
+					keys, check_time, good_keys);
+			/* try a little to get more descriptive error */
+			if(s == LDNS_STATUS_OK) {
+				verify_result = LDNS_STATUS_OK;
+			} else if(verify_result == LDNS_STATUS_ERR)
+				verify_result = s;
+			else if(s !=  LDNS_STATUS_ERR && verify_result ==
+				LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
+				verify_result = s;
+		}
+	}
+	return verify_result;
+}
+
+ldns_status
+ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys, 
+		  ldns_rr_list *good_keys)
+{
+	return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
+}
+
+ldns_status
+ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
+	const ldns_rr_list *keys, ldns_rr_list *good_keys)
+{
+	uint16_t i;
+	ldns_status verify_result = LDNS_STATUS_ERR;
+
+	if (!rrset || !rrsig || !keys) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (ldns_rr_list_rr_count(rrset) < 1) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (ldns_rr_list_rr_count(rrsig) < 1) {
+		return LDNS_STATUS_CRYPTO_NO_RRSIG;
+	}
+
+	if (ldns_rr_list_rr_count(keys) < 1) {
+		verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
+	} else {
+		for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
+			ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
+				ldns_rr_list_rr(rrsig, i), keys, good_keys);
+
+			/* try a little to get more descriptive error */
+			if (s == LDNS_STATUS_OK) {
+				verify_result = LDNS_STATUS_OK;
+			} else if (verify_result == LDNS_STATUS_ERR) {
+				verify_result = s;
+			} else if (s !=  LDNS_STATUS_ERR && verify_result ==
+				LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
+				verify_result = s;
+			}
+		}
+	}
+	return verify_result;
+}
+
+ldns_rr_list *
+ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
+                             const ldns_rdf *domain,
+                             const ldns_rr_list *keys,
+			     time_t check_time,
+                             ldns_status *status)
+{
+	ldns_rr_list * trusted_keys = NULL;
+	ldns_rr_list * ds_keys = NULL;
+	ldns_rdf * prev_parent_domain;
+	ldns_rdf *      parent_domain;
+	ldns_rr_list * parent_keys = NULL;
+
+	if (res && domain && keys) {
+
+		if ((trusted_keys = ldns_validate_domain_dnskey_time(res,
+                                         domain, keys, check_time))) {
+			*status = LDNS_STATUS_OK;
+		} else {
+			/* No trusted keys in this domain, we'll have to find some in the parent domain */
+			*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
+
+			parent_domain = ldns_dname_left_chop(domain);
+			while (parent_domain && /* Fail if we are at the root*/
+					ldns_rdf_size(parent_domain) > 0) {
+	
+				if ((parent_keys = 
+					ldns_fetch_valid_domain_keys_time(res,
+					     parent_domain,
+					     keys,
+					     check_time,
+					     status))) {
+					/* Check DS records */
+					if ((ds_keys =
+						ldns_validate_domain_ds_time(res,
+						     domain,
+						     parent_keys,
+						     check_time))) {
+						trusted_keys =
+						ldns_fetch_valid_domain_keys_time(
+								res, 
+								domain, 
+								ds_keys, 
+								check_time,
+								status);
+						ldns_rr_list_deep_free(ds_keys);
+					} else {
+						/* No valid DS at the parent -- fail */
+						*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
+					}
+					ldns_rr_list_deep_free(parent_keys);
+					break;
+				} else {
+					parent_domain = ldns_dname_left_chop((
+						prev_parent_domain 
+							= parent_domain
+						));
+					ldns_rdf_deep_free(prev_parent_domain);
+				}
+			}
+			if (parent_domain) {
+				ldns_rdf_deep_free(parent_domain);
+			}
+		}
+	}
+	return trusted_keys;
+}
+
+ldns_rr_list *
+ldns_fetch_valid_domain_keys(const ldns_resolver *res,
+                             const ldns_rdf *domain,
+                             const ldns_rr_list *keys,
+                             ldns_status *status)
+{
+	return ldns_fetch_valid_domain_keys_time(
+			res, domain, keys, ldns_time(NULL), status);
+}
+
+ldns_rr_list *
+ldns_validate_domain_dnskey_time(
+		const ldns_resolver * res,
+		const ldns_rdf * domain,
+		const ldns_rr_list * keys,
+		time_t check_time
+		)
+{
+	ldns_pkt * keypkt;
+	ldns_rr * cur_key;
+	uint16_t key_i; uint16_t key_j; uint16_t key_k;
+	uint16_t sig_i; ldns_rr * cur_sig;
+
+	ldns_rr_list * domain_keys = NULL;
+	ldns_rr_list * domain_sigs = NULL;
+	ldns_rr_list * trusted_keys = NULL;
+
+	/* Fetch keys for the domain */
+	keypkt = ldns_resolver_query(res, domain,
+		LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
+	if (keypkt) {
+		domain_keys = ldns_pkt_rr_list_by_type(keypkt,
+									    LDNS_RR_TYPE_DNSKEY,
+									    LDNS_SECTION_ANSWER);
+		domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
+									    LDNS_RR_TYPE_RRSIG,
+									    LDNS_SECTION_ANSWER);
+
+		/* Try to validate the record using our keys */
+		for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
+      
+			cur_key = ldns_rr_list_rr(domain_keys, key_i);
+			for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
+				if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
+								   cur_key)) {
+          
+					/* Current key is trusted -- validate */
+					trusted_keys = ldns_rr_list_new();
+          
+					for (sig_i=0;
+						sig_i<ldns_rr_list_rr_count(domain_sigs);
+						sig_i++) {
+						cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
+						/* Avoid non-matching sigs */
+						if (ldns_rdf2native_int16(
+							   ldns_rr_rrsig_keytag(cur_sig))
+						    == ldns_calc_keytag(cur_key)) {
+							if (ldns_verify_rrsig_time(
+									domain_keys,
+									cur_sig,
+									cur_key,
+									check_time)
+							    == LDNS_STATUS_OK) {
+                
+								/* Push the whole rrset 
+								   -- we can't do much more */
+								for (key_k=0;
+									key_k<ldns_rr_list_rr_count(
+											domain_keys);
+									key_k++) {
+									ldns_rr_list_push_rr(
+									    trusted_keys,
+									    ldns_rr_clone(
+										   ldns_rr_list_rr(
+											  domain_keys,
+											  key_k)));
+								}
+                
+								ldns_rr_list_deep_free(domain_keys);
+								ldns_rr_list_deep_free(domain_sigs);
+								ldns_pkt_free(keypkt);
+								return trusted_keys;
+							}
+						}
+					}
+	  
+					/* Only push our trusted key */
+					ldns_rr_list_push_rr(trusted_keys,
+									 ldns_rr_clone(cur_key));
+				}
+			}
+		}
+
+		ldns_rr_list_deep_free(domain_keys);
+		ldns_rr_list_deep_free(domain_sigs);
+		ldns_pkt_free(keypkt);
+
+	} else {
+		/* LDNS_STATUS_CRYPTO_NO_DNSKEY */
+	}
+    
+	return trusted_keys;
+}
+
+ldns_rr_list *
+ldns_validate_domain_dnskey(const ldns_resolver * res,
+					   const ldns_rdf * domain,
+					   const ldns_rr_list * keys)
+{
+	return ldns_validate_domain_dnskey_time(
+			res, domain, keys, ldns_time(NULL));
+}
+
+ldns_rr_list *
+ldns_validate_domain_ds_time(
+		const ldns_resolver *res, 
+		const ldns_rdf * domain,
+		const ldns_rr_list * keys,
+		time_t check_time)
+{
+	ldns_pkt * dspkt;
+	uint16_t key_i;
+	ldns_rr_list * rrset = NULL;
+	ldns_rr_list * sigs = NULL;
+	ldns_rr_list * trusted_keys = NULL;
+
+	/* Fetch DS for the domain */
+	dspkt = ldns_resolver_query(res, domain,
+		LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD);
+	if (dspkt) {
+		rrset = ldns_pkt_rr_list_by_type(dspkt,
+								   LDNS_RR_TYPE_DS,
+								   LDNS_SECTION_ANSWER);
+		sigs = ldns_pkt_rr_list_by_type(dspkt,
+								  LDNS_RR_TYPE_RRSIG,
+								  LDNS_SECTION_ANSWER);
+
+		/* Validate sigs */
+		if (ldns_verify_time(rrset, sigs, keys, check_time, NULL)
+			       	== LDNS_STATUS_OK) {
+			trusted_keys = ldns_rr_list_new();
+			for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
+				ldns_rr_list_push_rr(trusted_keys,
+								 ldns_rr_clone(ldns_rr_list_rr(rrset,
+														 key_i)
+											)
+								 );
+			}
+		}
+
+		ldns_rr_list_deep_free(rrset);
+		ldns_rr_list_deep_free(sigs);
+		ldns_pkt_free(dspkt);
+
+	} else {
+		/* LDNS_STATUS_CRYPTO_NO_DS */
+	}
+
+	return trusted_keys;
+}
+
+ldns_rr_list *
+ldns_validate_domain_ds(const ldns_resolver *res,
+				    const ldns_rdf * domain,
+				    const ldns_rr_list * keys)
+{
+	return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
+}
+
+ldns_status
+ldns_verify_trusted_time(
+		ldns_resolver *res, 
+		ldns_rr_list *rrset, 
+		ldns_rr_list * rrsigs, 
+		time_t check_time,
+		ldns_rr_list * validating_keys
+		)
+{
+	uint16_t sig_i; uint16_t key_i;
+	ldns_rr * cur_sig; ldns_rr * cur_key;
+	ldns_rr_list * trusted_keys = NULL;
+	ldns_status result = LDNS_STATUS_ERR;
+
+	if (!res || !rrset || !rrsigs) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (ldns_rr_list_rr_count(rrset) < 1) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (ldns_rr_list_rr_count(rrsigs) < 1) {
+		return LDNS_STATUS_CRYPTO_NO_RRSIG;
+	}
+  
+	/* Look at each sig */
+	for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
+
+		cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
+		/* Get a valid signer key and validate the sig */
+		if ((trusted_keys = ldns_fetch_valid_domain_keys_time(
+					res, 
+					ldns_rr_rrsig_signame(cur_sig), 
+					ldns_resolver_dnssec_anchors(res), 
+					check_time,
+					&result))) {
+
+			for (key_i = 0;
+				key_i < ldns_rr_list_rr_count(trusted_keys);
+				key_i++) {
+				cur_key = ldns_rr_list_rr(trusted_keys, key_i);
+
+				if ((result = ldns_verify_rrsig_time(rrset,
+								cur_sig, 
+								cur_key,
+								check_time))
+				    == LDNS_STATUS_OK) {
+					if (validating_keys) {
+						ldns_rr_list_push_rr(validating_keys,
+										 ldns_rr_clone(cur_key));
+					}
+					ldns_rr_list_deep_free(trusted_keys);
+					return LDNS_STATUS_OK;
+				} 
+			}
+		}
+	}
+
+	ldns_rr_list_deep_free(trusted_keys);
+	return result;
+}
+
+ldns_status
+ldns_verify_trusted(
+		ldns_resolver *res,
+		ldns_rr_list *rrset, 
+		ldns_rr_list * rrsigs, 
+		ldns_rr_list * validating_keys)
+{
+	return ldns_verify_trusted_time(
+			res, rrset, rrsigs, ldns_time(NULL), validating_keys);
+}
+
+
+ldns_status
+ldns_dnssec_verify_denial(ldns_rr *rr,
+                          ldns_rr_list *nsecs,
+                          ldns_rr_list *rrsigs)
+{
+	ldns_rdf *rr_name;
+	ldns_rdf *wildcard_name;
+	ldns_rdf *chopped_dname;
+	ldns_rr *cur_nsec;
+	size_t i;
+	ldns_status result;
+	/* needed for wildcard check on exact match */
+	ldns_rr *rrsig;
+	bool name_covered = false;
+	bool type_covered = false;
+	bool wildcard_covered = false;
+	bool wildcard_type_covered = false;
+
+	wildcard_name = ldns_dname_new_frm_str("*");
+	rr_name = ldns_rr_owner(rr);
+	chopped_dname = ldns_dname_left_chop(rr_name);
+	result = ldns_dname_cat(wildcard_name, chopped_dname);
+	ldns_rdf_deep_free(chopped_dname);
+	if (result != LDNS_STATUS_OK) {
+		return result;
+	}
+	
+	for  (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+		cur_nsec = ldns_rr_list_rr(nsecs, i);
+		if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
+			/* see section 5.4 of RFC4035, if the label count of the NSEC's
+			   RRSIG is equal, then it is proven that wildcard expansion 
+			   could not have been used to match the request */
+			rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
+					  ldns_rr_owner(cur_nsec),
+					  ldns_rr_get_type(cur_nsec),
+					  rrsigs);
+			if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
+			    == ldns_dname_label_count(rr_name)) {
+				wildcard_covered = true;
+			}
+			
+			if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
+									   ldns_rr_get_type(rr))) {
+				type_covered = true;
+			}
+		}
+		if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
+			name_covered = true;
+		}
+		
+		if (ldns_dname_compare(wildcard_name,
+						   ldns_rr_owner(cur_nsec)) == 0) {
+			if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
+									   ldns_rr_get_type(rr))) {
+				wildcard_type_covered = true;
+			}
+		}
+		
+		if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
+			wildcard_covered = true;
+		}
+		
+	}
+	
+	ldns_rdf_deep_free(wildcard_name);
+	
+	if (type_covered || !name_covered) {
+		return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+	}
+	
+	if (wildcard_type_covered || !wildcard_covered) {
+		return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
+	}
+
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
+				     , ldns_rr_list *nsecs
+				     , ATTR_UNUSED(ldns_rr_list *rrsigs)
+				     , ldns_pkt_rcode packet_rcode
+				     , ldns_rr_type packet_qtype
+				     , bool packet_nodata
+				     , ldns_rr **match
+				     )
+{
+	ldns_rdf *closest_encloser;
+	ldns_rdf *wildcard;
+	ldns_rdf *hashed_wildcard_name;
+	bool wildcard_covered = false;
+	ldns_rdf *zone_name;
+	ldns_rdf *hashed_name;
+	/* self assignment to suppress uninitialized warning */
+	ldns_rdf *next_closer = next_closer;
+	ldns_rdf *hashed_next_closer;
+	size_t i;
+	ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+
+	if (match) {
+		*match = NULL;
+	}
+
+	zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
+
+	/* section 8.4 */
+	if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
+		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
+						   ldns_rr_owner(rr),
+						   ldns_rr_get_type(rr),
+						   nsecs);
+                if(!closest_encloser) {
+                        result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+                        goto done;
+                }
+
+		wildcard = ldns_dname_new_frm_str("*");
+		(void) ldns_dname_cat(wildcard, closest_encloser);
+
+		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+			hashed_wildcard_name =
+				ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
+										 wildcard
+										 );
+			(void) ldns_dname_cat(hashed_wildcard_name, zone_name);
+
+			if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
+								 hashed_wildcard_name)) {
+				wildcard_covered = true;
+				if (match) {
+					*match = ldns_rr_list_rr(nsecs, i);
+				}
+			}
+			ldns_rdf_deep_free(hashed_wildcard_name);
+		}
+
+		if (! wildcard_covered) {
+			result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
+		} else {
+			result = LDNS_STATUS_OK;
+		}
+		ldns_rdf_deep_free(closest_encloser);
+		ldns_rdf_deep_free(wildcard);
+
+	} else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
+		/* section 8.5 */
+		hashed_name = ldns_nsec3_hash_name_frm_nsec3(
+		                   ldns_rr_list_rr(nsecs, 0),
+		                   ldns_rr_owner(rr));
+		(void) ldns_dname_cat(hashed_name, zone_name);
+		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+			if (ldns_dname_compare(hashed_name,
+			         ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
+			    == 0) {
+				if (!ldns_nsec_bitmap_covers_type(
+					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
+					    packet_qtype)
+				    &&
+				    !ldns_nsec_bitmap_covers_type(
+					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
+					    LDNS_RR_TYPE_CNAME)) {
+					result = LDNS_STATUS_OK;
+					if (match) {
+						*match = ldns_rr_list_rr(nsecs, i);
+					}
+					goto done;
+				}
+			}
+		}
+		result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+		/* wildcard no data? section 8.7 */
+		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
+				   ldns_rr_owner(rr),
+				   ldns_rr_get_type(rr),
+				   nsecs);
+		if(!closest_encloser) {
+			result = LDNS_STATUS_NSEC3_ERR;
+			goto done;
+		}
+		wildcard = ldns_dname_new_frm_str("*");
+		(void) ldns_dname_cat(wildcard, closest_encloser);
+		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+			hashed_wildcard_name =
+				ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
+					 wildcard);
+			(void) ldns_dname_cat(hashed_wildcard_name, zone_name);
+
+			if (ldns_dname_compare(hashed_wildcard_name,
+			         ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
+			    == 0) {
+				if (!ldns_nsec_bitmap_covers_type(
+					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
+					    packet_qtype)
+				    &&
+				    !ldns_nsec_bitmap_covers_type(
+					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
+					    LDNS_RR_TYPE_CNAME)) {
+					result = LDNS_STATUS_OK;
+					if (match) {
+						*match = ldns_rr_list_rr(nsecs, i);
+					}
+				}
+			}
+			ldns_rdf_deep_free(hashed_wildcard_name);
+			if (result == LDNS_STATUS_OK) {
+				break;
+			}
+		}
+		ldns_rdf_deep_free(closest_encloser);
+		ldns_rdf_deep_free(wildcard);
+	} else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
+		/* section 8.6 */
+		/* note: up to XXX this is the same as for 8.5 */
+		hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
+														 0),
+											ldns_rr_owner(rr)
+											);
+		(void) ldns_dname_cat(hashed_name, zone_name);
+		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+			if (ldns_dname_compare(hashed_name,
+							   ldns_rr_owner(ldns_rr_list_rr(nsecs,
+													   i)))
+			    == 0) {
+				if (!ldns_nsec_bitmap_covers_type(
+					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
+					    LDNS_RR_TYPE_DS)
+				    && 
+				    !ldns_nsec_bitmap_covers_type(
+					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
+					    LDNS_RR_TYPE_CNAME)) {
+					result = LDNS_STATUS_OK;
+					if (match) {
+						*match = ldns_rr_list_rr(nsecs, i);
+					}
+					goto done;
+				}
+			}
+		}
+
+		/* XXX see note above */
+		result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+
+		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
+				   ldns_rr_owner(rr),
+				   ldns_rr_get_type(rr),
+				   nsecs);
+		if(!closest_encloser) {
+			result = LDNS_STATUS_NSEC3_ERR;
+			goto done;
+		}
+		/* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
+
+		if (ldns_dname_label_count(closest_encloser) + 1
+		    >= ldns_dname_label_count(ldns_rr_owner(rr))) {
+			
+			/* Query name *is* the "next closer". */
+			hashed_next_closer = hashed_name;
+		} else {
+
+			/* "next closer" has less labels than the query name.
+			 * Create the name and hash it.
+			 */
+			next_closer = ldns_dname_clone_from(
+					ldns_rr_owner(rr),
+					ldns_dname_label_count(ldns_rr_owner(rr))
+					- (ldns_dname_label_count(closest_encloser) + 1)
+					);
+			hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
+					ldns_rr_list_rr(nsecs, 0),
+					next_closer
+					);
+			(void) ldns_dname_cat(hashed_next_closer, zone_name);
+		}
+		/* Find the NSEC3 that covers the "next closer" */
+		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+			if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
+			                          hashed_next_closer) && 
+				ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
+
+				result = LDNS_STATUS_OK;
+				if (match) {
+					*match = ldns_rr_list_rr(nsecs, i);
+				}
+				break;
+			}
+		}
+		if (ldns_dname_label_count(closest_encloser) + 1
+		    < ldns_dname_label_count(ldns_rr_owner(rr))) {
+
+			/* "next closer" has less labels than the query name.
+			 * Dispose of the temporary variables that held that name.
+			 */
+			ldns_rdf_deep_free(hashed_next_closer);
+			ldns_rdf_deep_free(next_closer);
+		}
+		ldns_rdf_deep_free(closest_encloser);
+	}
+
+ done:
+	ldns_rdf_deep_free(zone_name);
+	return result;
+}
+
+ldns_status
+ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
+						  ldns_rr_list *nsecs,
+						  ldns_rr_list *rrsigs,
+						  ldns_pkt_rcode packet_rcode,
+						  ldns_rr_type packet_qtype,
+						  bool packet_nodata)
+{
+	return ldns_dnssec_verify_denial_nsec3_match(
+				rr, nsecs, rrsigs, packet_rcode,
+				packet_qtype, packet_nodata, NULL
+	       );
+}
+
+#ifdef USE_GOST
+EVP_PKEY*
+ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
+{
+	/* prefix header for X509 encoding */
+	uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 
+		0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 
+		0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 
+		0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
+	unsigned char encoded[37+64];
+	const unsigned char* pp;
+	if(keylen != 64) {
+		/* key wrong size */
+		return NULL;
+	}
+
+	/* create evp_key */
+	memmove(encoded, asn, 37);
+	memmove(encoded+37, key, 64);
+	pp = (unsigned char*)&encoded[0];
+
+	return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
+}
+
+static ldns_status
+ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen, 
+	ldns_buffer* rrset, unsigned char* key, size_t keylen)
+{
+	EVP_PKEY *evp_key;
+	ldns_status result;
+
+	(void) ldns_key_EVP_load_gost_id();
+	evp_key = ldns_gost2pkey_raw(key, keylen);
+	if(!evp_key) {
+		/* could not convert key */
+		return LDNS_STATUS_CRYPTO_BOGUS;
+	}
+
+	/* verify signature */
+	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, 
+		evp_key, EVP_get_digestbyname("md_gost94"));
+	EVP_PKEY_free(evp_key);
+
+	return result;
+}
+#endif
+
+#ifdef USE_ECDSA
+EVP_PKEY*
+ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
+{
+	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
+        const unsigned char* pp = buf;
+        EVP_PKEY *evp_key;
+        EC_KEY *ec;
+	/* check length, which uncompressed must be 2 bignums */
+        if(algo == LDNS_ECDSAP256SHA256) {
+		if(keylen != 2*256/8) return NULL;
+                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+        } else if(algo == LDNS_ECDSAP384SHA384) {
+		if(keylen != 2*384/8) return NULL;
+                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
+        } else    ec = NULL;
+        if(!ec) return NULL;
+	if(keylen+1 > sizeof(buf))
+		return NULL; /* sanity check */
+	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
+	 * of openssl) for uncompressed data */
+	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
+	memmove(buf+1, key, keylen);
+        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        evp_key = EVP_PKEY_new();
+        if(!evp_key) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
+		EVP_PKEY_free(evp_key);
+		EC_KEY_free(ec);
+		return NULL;
+	}
+        return evp_key;
+}
+
+static ldns_status
+ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen, 
+	ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
+{
+        EVP_PKEY *evp_key;
+        ldns_status result;
+        const EVP_MD *d;
+
+        evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
+        if(!evp_key) {
+		/* could not convert key */
+		return LDNS_STATUS_CRYPTO_BOGUS;
+        }
+        if(algo == LDNS_ECDSAP256SHA256)
+                d = EVP_sha256();
+        else    d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
+	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
+	EVP_PKEY_free(evp_key);
+	return result;
+}
+#endif
+
+ldns_status
+ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf, 
+					 ldns_buffer *key_buf, uint8_t algo)
+{
+	return ldns_verify_rrsig_buffers_raw(
+			 (unsigned char*)ldns_buffer_begin(rawsig_buf),
+			 ldns_buffer_position(rawsig_buf),
+			 verify_buf,
+			 (unsigned char*)ldns_buffer_begin(key_buf), 
+			 ldns_buffer_position(key_buf), algo);
+}
+
+ldns_status
+ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
+						ldns_buffer *verify_buf, unsigned char* key, size_t keylen, 
+						uint8_t algo)
+{
+	/* check for right key */
+	switch(algo) {
+	case LDNS_DSA:
+	case LDNS_DSA_NSEC3:
+		return ldns_verify_rrsig_dsa_raw(sig,
+								   siglen,
+								   verify_buf,
+								   key,
+								   keylen);
+		break;
+	case LDNS_RSASHA1:
+	case LDNS_RSASHA1_NSEC3:
+		return ldns_verify_rrsig_rsasha1_raw(sig,
+									  siglen,
+									  verify_buf,
+									  key,
+									  keylen);
+		break;
+#ifdef USE_SHA2
+	case LDNS_RSASHA256:
+		return ldns_verify_rrsig_rsasha256_raw(sig,
+									    siglen,
+									    verify_buf,
+									    key,
+									    keylen);
+		break;
+	case LDNS_RSASHA512:
+		return ldns_verify_rrsig_rsasha512_raw(sig,
+									    siglen,
+									    verify_buf,
+									    key,
+									    keylen);
+		break;
+#endif
+#ifdef USE_GOST
+	case LDNS_ECC_GOST:
+		return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
+			key, keylen);
+		break;
+#endif
+#ifdef USE_ECDSA
+        case LDNS_ECDSAP256SHA256:
+        case LDNS_ECDSAP384SHA384:
+		return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
+			key, keylen, algo);
+		break;
+#endif
+	case LDNS_RSAMD5:
+		return ldns_verify_rrsig_rsamd5_raw(sig,
+									 siglen,
+									 verify_buf,
+									 key,
+									 keylen);
+		break;
+	default:
+		/* do you know this alg?! */
+		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
+	}
+}
+
+
+/**
+ * Reset the ttl in the rrset with the orig_ttl from the sig 
+ * and update owner name if it was wildcard 
+ * Also canonicalizes the rrset.
+ * @param rrset: rrset to modify
+ * @param sig: signature to take TTL and wildcard values from
+ */
+static void
+ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
+{
+	uint32_t orig_ttl;
+	uint16_t i;
+	uint8_t label_count;
+	ldns_rdf *wildcard_name;
+	ldns_rdf *wildcard_chopped;
+	ldns_rdf *wildcard_chopped_tmp;
+	
+	if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
+		return;
+	}
+
+	orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
+	label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
+
+	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
+		if (label_count < 
+		    ldns_dname_label_count(
+			   ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
+			(void) ldns_str2rdf_dname(&wildcard_name, "*");
+			wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
+				ldns_rr_list_rr(rrset_clone, i)));
+			while (label_count < ldns_dname_label_count(wildcard_chopped)) {
+				wildcard_chopped_tmp = ldns_dname_left_chop(
+					wildcard_chopped);
+				ldns_rdf_deep_free(wildcard_chopped);
+				wildcard_chopped = wildcard_chopped_tmp;
+			}
+			(void) ldns_dname_cat(wildcard_name, wildcard_chopped);
+			ldns_rdf_deep_free(wildcard_chopped);
+			ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
+				rrset_clone, i)));
+			ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), 
+				wildcard_name);
+		}
+		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
+		/* convert to lowercase */
+		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
+	}
+}
+
+/**
+ * Make raw signature buffer out of rrsig
+ * @param rawsig_buf: raw signature buffer for result
+ * @param rrsig: signature to convert
+ * @return OK or more specific error.
+ */
+static ldns_status
+ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
+{
+	uint8_t sig_algo;
+       
+	if (rrsig == NULL) {
+		return LDNS_STATUS_CRYPTO_NO_RRSIG;
+	}
+	if (ldns_rr_rdf(rrsig, 1) == NULL) {
+		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+	}
+	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
+	/* check for known and implemented algo's now (otherwise 
+	 * the function could return a wrong error
+	 */
+	/* create a buffer with signature rdata */
+	/* for some algorithms we need other data than for others... */
+	/* (the DSA API wants DER encoding for instance) */
+
+	switch(sig_algo) {
+	case LDNS_RSAMD5:
+	case LDNS_RSASHA1:
+	case LDNS_RSASHA1_NSEC3:
+#ifdef USE_SHA2
+	case LDNS_RSASHA256:
+	case LDNS_RSASHA512:
+#endif
+#ifdef USE_GOST
+	case LDNS_ECC_GOST:
+#endif
+		if (ldns_rr_rdf(rrsig, 8) == NULL) {
+			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+		}
+		if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
+			       	!= LDNS_STATUS_OK) {
+			return LDNS_STATUS_MEM_ERR;
+		}
+		break;
+	case LDNS_DSA:
+	case LDNS_DSA_NSEC3:
+		/* EVP takes rfc2459 format, which is a tad longer than dns format */
+		if (ldns_rr_rdf(rrsig, 8) == NULL) {
+			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+		}
+		if (ldns_convert_dsa_rrsig_rdf2asn1(
+					rawsig_buf, ldns_rr_rdf(rrsig, 8)) 
+				!= LDNS_STATUS_OK) {
+			/*
+			  if (ldns_rdf2buffer_wire(rawsig_buf,
+			  ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+			*/
+			return LDNS_STATUS_MEM_ERR;
+		}
+		break;
+#ifdef USE_ECDSA
+        case LDNS_ECDSAP256SHA256:
+        case LDNS_ECDSAP384SHA384:
+                /* EVP produces an ASN prefix on the signature, which is
+                 * not used in the DNS */
+		if (ldns_rr_rdf(rrsig, 8) == NULL) {
+			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+		}
+		if (ldns_convert_ecdsa_rrsig_rdf2asn1(
+					rawsig_buf, ldns_rr_rdf(rrsig, 8))
+				!= LDNS_STATUS_OK) {
+			return LDNS_STATUS_MEM_ERR;
+                }
+                break;
+#endif
+	case LDNS_DH:
+	case LDNS_ECC:
+	case LDNS_INDIRECT:
+		return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
+	default:
+		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
+	}
+	return LDNS_STATUS_OK;
+}
+
+/**
+ * Check RRSIG timestamps against the given 'now' time.
+ * @param rrsig: signature to check.
+ * @param now: the current time in seconds epoch.
+ * @return status code LDNS_STATUS_OK if all is fine.
+ */
+static ldns_status
+ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
+{
+	int32_t inception, expiration;
+	
+	/* check the signature time stamps */
+	inception = (int32_t)ldns_rdf2native_time_t(
+		ldns_rr_rrsig_inception(rrsig));
+	expiration = (int32_t)ldns_rdf2native_time_t(
+		ldns_rr_rrsig_expiration(rrsig));
+
+	if (expiration - inception < 0) {
+		/* bad sig, expiration before inception?? Tsssg */
+		return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
+	}
+	if (((int32_t) now) - inception < 0) {
+		/* bad sig, inception date has not yet come to pass */
+		return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
+	}
+	if (expiration - ((int32_t) now) < 0) {
+		/* bad sig, expiration date has passed */
+		return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
+	}
+	return LDNS_STATUS_OK;
+}
+
+/**
+ * Prepare for verification.
+ * @param rawsig_buf: raw signature buffer made ready.
+ * @param verify_buf: data for verification buffer made ready.
+ * @param rrset_clone: made ready.
+ * @param rrsig: signature to prepare for.
+ * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
+ */
+static ldns_status
+ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
+	ldns_rr_list* rrset_clone, ldns_rr* rrsig)
+{
+	ldns_status result;
+
+	/* canonicalize the sig */
+	ldns_dname2canonical(ldns_rr_owner(rrsig));
+	
+	/* check if the typecovered is equal to the type checked */
+	if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
+	    ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
+		return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
+	
+	/* create a buffer with b64 signature rdata */
+	result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
+	if(result != LDNS_STATUS_OK)
+		return result;
+
+	/* use TTL from signature. Use wildcard names for wildcards */
+	/* also canonicalizes rrset_clone */
+	ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
+
+	/* sort the rrset in canonical order  */
+	ldns_rr_list_sort(rrset_clone);
+
+	/* put the signature rr (without the b64) to the verify_buf */
+	if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
+		return LDNS_STATUS_MEM_ERR;
+
+	/* add the rrset in verify_buf */
+	if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone) 
+		!= LDNS_STATUS_OK)
+		return LDNS_STATUS_MEM_ERR;
+
+	return LDNS_STATUS_OK;
+}
+
+/**
+ * Check if a key matches a signature.
+ * Checks keytag, sigalgo and signature.
+ * @param rawsig_buf: raw signature buffer for verify
+ * @param verify_buf: raw data buffer for verify
+ * @param rrsig: the rrsig
+ * @param key: key to attempt.
+ * @return LDNS_STATUS_OK if OK, else some specific error.
+ */
+static ldns_status
+ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
+	ldns_rr* rrsig, ldns_rr* key)
+{
+	uint8_t sig_algo;
+       
+	if (rrsig == NULL) {
+		return LDNS_STATUS_CRYPTO_NO_RRSIG;
+	}
+	if (ldns_rr_rdf(rrsig, 1) == NULL) {
+		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
+	}
+	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
+
+	/* before anything, check if the keytags match */
+	if (ldns_calc_keytag(key)
+	    ==
+	    ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
+	    ) {
+		ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+		ldns_status result = LDNS_STATUS_ERR;
+
+		/* put the key-data in a buffer, that's the third rdf, with
+		 * the base64 encoded key data */
+		if (ldns_rr_rdf(key, 3) == NULL) {
+			ldns_buffer_free(key_buf);
+			return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
+		}
+		if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
+			       	!= LDNS_STATUS_OK) {
+			ldns_buffer_free(key_buf); 
+			/* returning is bad might screw up
+			   good keys later in the list
+			   what to do? */
+			return LDNS_STATUS_ERR;
+		}
+
+		if (ldns_rr_rdf(key, 2) == NULL) {
+			result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
+		}
+		else if (sig_algo == ldns_rdf2native_int8(
+					ldns_rr_rdf(key, 2))) {
+			result = ldns_verify_rrsig_buffers(rawsig_buf, 
+				verify_buf, key_buf, sig_algo);
+		} else {
+			/* No keys with the corresponding algorithm are found */
+			result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
+		}
+
+		ldns_buffer_free(key_buf); 
+		return result;
+	}
+	else {
+		/* No keys with the corresponding keytag are found */
+		return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
+	}
+}
+
+/* 
+ * to verify:
+ * - create the wire fmt of the b64 key rdata
+ * - create the wire fmt of the sorted rrset
+ * - create the wire fmt of the b64 sig rdata
+ * - create the wire fmt of the sig without the b64 rdata
+ * - cat the sig data (without b64 rdata) to the rrset
+ * - verify the rrset+sig, with the b64 data and the b64 key data
+ */
+ldns_status
+ldns_verify_rrsig_keylist_time(
+		ldns_rr_list *rrset,
+		ldns_rr *rrsig,
+		const ldns_rr_list *keys, 
+		time_t check_time,
+		ldns_rr_list *good_keys)
+{
+	ldns_status result;
+	ldns_rr_list *valid = ldns_rr_list_new();
+	if (!valid)
+		return LDNS_STATUS_MEM_ERR;
+
+	result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
+	if(result != LDNS_STATUS_OK) {
+		ldns_rr_list_free(valid); 
+		return result;
+	}
+
+	/* check timestamps last; its OK except time */
+	result = ldns_rrsig_check_timestamps(rrsig, check_time);
+	if(result != LDNS_STATUS_OK) {
+		ldns_rr_list_free(valid); 
+		return result;
+	}
+
+	ldns_rr_list_cat(good_keys, valid);
+	ldns_rr_list_free(valid);
+	return LDNS_STATUS_OK;
+}
+
+/* 
+ * to verify:
+ * - create the wire fmt of the b64 key rdata
+ * - create the wire fmt of the sorted rrset
+ * - create the wire fmt of the b64 sig rdata
+ * - create the wire fmt of the sig without the b64 rdata
+ * - cat the sig data (without b64 rdata) to the rrset
+ * - verify the rrset+sig, with the b64 data and the b64 key data
+ */
+ldns_status
+ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
+					 ldns_rr *rrsig,
+					 const ldns_rr_list *keys, 
+					 ldns_rr_list *good_keys)
+{
+	return ldns_verify_rrsig_keylist_time(
+			rrset, rrsig, keys, ldns_time(NULL), good_keys);
+}
+
+ldns_status
+ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
+					 ldns_rr *rrsig,
+					 const ldns_rr_list *keys, 
+					 ldns_rr_list *good_keys)
+{
+	ldns_buffer *rawsig_buf;
+	ldns_buffer *verify_buf;
+	uint16_t i;
+	ldns_status result, status;
+	ldns_rr_list *rrset_clone;
+	ldns_rr_list *validkeys;
+
+	if (!rrset) {
+		return LDNS_STATUS_ERR;
+	}
+
+	validkeys = ldns_rr_list_new();
+	if (!validkeys) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	
+	/* clone the rrset so that we can fiddle with it */
+	rrset_clone = ldns_rr_list_clone(rrset);
+
+	/* create the buffers which will certainly hold the raw data */
+	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+
+	result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 
+		rrset_clone, rrsig);
+	if(result != LDNS_STATUS_OK) {
+		ldns_buffer_free(verify_buf);
+		ldns_buffer_free(rawsig_buf);
+		ldns_rr_list_deep_free(rrset_clone);
+		ldns_rr_list_free(validkeys);
+		return result;
+	}
+
+	result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
+	for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
+		status = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
+			rrsig, ldns_rr_list_rr(keys, i));
+		if (status == LDNS_STATUS_OK) {
+			/* one of the keys has matched, don't break
+			 * here, instead put the 'winning' key in
+			 * the validkey list and return the list 
+			 * later */
+			if (!ldns_rr_list_push_rr(validkeys, 
+				ldns_rr_list_rr(keys,i))) {
+				/* couldn't push the key?? */
+				ldns_buffer_free(rawsig_buf);
+				ldns_buffer_free(verify_buf);
+				ldns_rr_list_deep_free(rrset_clone);
+				ldns_rr_list_free(validkeys);
+				return LDNS_STATUS_MEM_ERR;
+			}
+
+			result = status;
+		}
+
+		if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
+			result = status;
+		}
+	}
+
+	/* no longer needed */
+	ldns_rr_list_deep_free(rrset_clone);
+	ldns_buffer_free(rawsig_buf);
+	ldns_buffer_free(verify_buf);
+
+	if (ldns_rr_list_rr_count(validkeys) == 0) {
+		/* no keys were added, return last error */
+		ldns_rr_list_free(validkeys); 
+		return result;
+	}
+
+	/* do not check timestamps */
+
+	ldns_rr_list_cat(good_keys, validkeys);
+	ldns_rr_list_free(validkeys);
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_verify_rrsig_time(
+		ldns_rr_list *rrset, 
+		ldns_rr *rrsig, 
+		ldns_rr *key, 
+		time_t check_time)
+{
+	ldns_buffer *rawsig_buf;
+	ldns_buffer *verify_buf;
+	ldns_status result;
+	ldns_rr_list *rrset_clone;
+
+	if (!rrset) {
+		return LDNS_STATUS_NO_DATA;
+	}
+	/* clone the rrset so that we can fiddle with it */
+	rrset_clone = ldns_rr_list_clone(rrset);
+	/* create the buffers which will certainly hold the raw data */
+	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+
+	result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 
+		rrset_clone, rrsig);
+	if(result != LDNS_STATUS_OK) {
+		ldns_rr_list_deep_free(rrset_clone);
+		ldns_buffer_free(rawsig_buf);
+		ldns_buffer_free(verify_buf);
+		return result;
+	}
+	result = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
+		rrsig, key);
+	/* no longer needed */
+	ldns_rr_list_deep_free(rrset_clone);
+	ldns_buffer_free(rawsig_buf);
+	ldns_buffer_free(verify_buf);
+
+	/* check timestamp last, apart from time its OK */
+	if(result == LDNS_STATUS_OK)
+		result = ldns_rrsig_check_timestamps(rrsig, check_time);
+
+	return result;
+}
+
+ldns_status
+ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
+{
+	return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
+}
+
+
+ldns_status
+ldns_verify_rrsig_evp(ldns_buffer *sig,
+				  ldns_buffer *rrset,
+				  EVP_PKEY *key,
+				  const EVP_MD *digest_type)
+{
+	return ldns_verify_rrsig_evp_raw(
+			 (unsigned char*)ldns_buffer_begin(sig),
+			 ldns_buffer_position(sig),
+			 rrset,
+			 key,
+			 digest_type);
+}
+
+ldns_status
+ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen, 
+					 ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
+{
+	EVP_MD_CTX ctx;
+	int res;
+
+	EVP_MD_CTX_init(&ctx);
+	
+	EVP_VerifyInit(&ctx, digest_type);
+	EVP_VerifyUpdate(&ctx,
+				  ldns_buffer_begin(rrset),
+				  ldns_buffer_position(rrset));
+	res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
+	
+	EVP_MD_CTX_cleanup(&ctx);
+	
+	if (res == 1) {
+		return LDNS_STATUS_OK;
+	} else if (res == 0) {
+		return LDNS_STATUS_CRYPTO_BOGUS;
+	}
+	/* TODO how to communicate internal SSL error?
+	   let caller use ssl's get_error() */
+	return LDNS_STATUS_SSL_ERR;
+}
+
+ldns_status
+ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
+{
+	return ldns_verify_rrsig_dsa_raw(
+			 (unsigned char*) ldns_buffer_begin(sig),
+			 ldns_buffer_position(sig),
+			 rrset,
+			 (unsigned char*) ldns_buffer_begin(key),
+			 ldns_buffer_position(key));
+}
+
+ldns_status
+ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
+{
+	return ldns_verify_rrsig_rsasha1_raw(
+			 (unsigned char*)ldns_buffer_begin(sig),
+			 ldns_buffer_position(sig),
+			 rrset,
+			 (unsigned char*) ldns_buffer_begin(key),
+			 ldns_buffer_position(key));
+}
+
+ldns_status
+ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
+{
+	return ldns_verify_rrsig_rsamd5_raw(
+			 (unsigned char*)ldns_buffer_begin(sig),
+			 ldns_buffer_position(sig),
+			 rrset,
+			 (unsigned char*) ldns_buffer_begin(key),
+			 ldns_buffer_position(key));
+}
+
+ldns_status
+ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
+					 ldns_buffer* rrset, unsigned char* key, size_t keylen)
+{
+	EVP_PKEY *evp_key;
+	ldns_status result;
+
+	evp_key = EVP_PKEY_new();
+	if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
+		result = ldns_verify_rrsig_evp_raw(sig,
+								siglen,
+								rrset,
+								evp_key,
+								EVP_dss1());
+	} else {
+		result = LDNS_STATUS_SSL_ERR;
+	}
+	EVP_PKEY_free(evp_key);
+	return result;
+
+}
+
+ldns_status
+ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
+						ldns_buffer* rrset, unsigned char* key, size_t keylen)
+{
+	EVP_PKEY *evp_key;
+	ldns_status result;
+
+	evp_key = EVP_PKEY_new();
+	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
+		result = ldns_verify_rrsig_evp_raw(sig,
+								siglen,
+								rrset,
+								evp_key,
+								EVP_sha1());
+	} else {
+		result = LDNS_STATUS_SSL_ERR;
+	}
+	EVP_PKEY_free(evp_key);
+
+	return result;
+}
+
+ldns_status
+ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
+						  size_t siglen,
+						  ldns_buffer* rrset,
+						  unsigned char* key,
+						  size_t keylen)
+{
+#ifdef USE_SHA2
+	EVP_PKEY *evp_key;
+	ldns_status result;
+
+	evp_key = EVP_PKEY_new();
+	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
+		result = ldns_verify_rrsig_evp_raw(sig,
+								siglen,
+								rrset,
+								evp_key,
+								EVP_sha256());
+	} else {
+		result = LDNS_STATUS_SSL_ERR;
+	}
+	EVP_PKEY_free(evp_key);
+
+	return result;
+#else
+	/* touch these to prevent compiler warnings */
+	(void) sig;
+	(void) siglen;
+	(void) rrset;
+	(void) key;
+	(void) keylen;
+	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
+#endif
+}
+
+ldns_status
+ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
+						  size_t siglen,
+						  ldns_buffer* rrset,
+						  unsigned char* key,
+						  size_t keylen)
+{
+#ifdef USE_SHA2
+	EVP_PKEY *evp_key;
+	ldns_status result;
+
+	evp_key = EVP_PKEY_new();
+	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
+		result = ldns_verify_rrsig_evp_raw(sig,
+								siglen,
+								rrset,
+								evp_key,
+								EVP_sha512());
+	} else {
+		result = LDNS_STATUS_SSL_ERR;
+	}
+	EVP_PKEY_free(evp_key);
+
+	return result;
+#else
+	/* touch these to prevent compiler warnings */
+	(void) sig;
+	(void) siglen;
+	(void) rrset;
+	(void) key;
+	(void) keylen;
+	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
+#endif
+}
+
+
+ldns_status
+ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
+					    size_t siglen,
+					    ldns_buffer* rrset,
+					    unsigned char* key,
+					    size_t keylen)
+{
+	EVP_PKEY *evp_key;
+	ldns_status result;
+
+	evp_key = EVP_PKEY_new();
+	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
+		result = ldns_verify_rrsig_evp_raw(sig,
+								siglen,
+								rrset,
+								evp_key,
+								EVP_md5());
+	} else {
+		result = LDNS_STATUS_SSL_ERR;
+	}
+	EVP_PKEY_free(evp_key);
+
+	return result;
+}
+
+#endif
diff --git a/ldns/src/dnssec_zone.c b/ldns/src/dnssec_zone.c
new file mode 100644
index 0000000..0fec48c
--- /dev/null
+++ b/ldns/src/dnssec_zone.c
@@ -0,0 +1,1192 @@
+/*
+ * special zone file structures and functions for better dnssec handling
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+ldns_dnssec_rrs *
+ldns_dnssec_rrs_new(void)
+{
+	ldns_dnssec_rrs *new_rrs;
+	new_rrs = LDNS_MALLOC(ldns_dnssec_rrs);
+        if(!new_rrs) return NULL;
+	new_rrs->rr = NULL;
+	new_rrs->next = NULL;
+	return new_rrs;
+}
+
+INLINE void
+ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep)
+{
+	ldns_dnssec_rrs *next;
+	while (rrs) {
+		next = rrs->next;
+		if (deep) {
+			ldns_rr_free(rrs->rr);
+		}
+		LDNS_FREE(rrs);
+		rrs = next;
+	}
+}
+
+void
+ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs)
+{
+	ldns_dnssec_rrs_free_internal(rrs, 0);
+}
+
+void
+ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs)
+{
+	ldns_dnssec_rrs_free_internal(rrs, 1);
+}
+
+ldns_status
+ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
+{
+	int cmp;
+	ldns_dnssec_rrs *new_rrs;
+	if (!rrs || !rr) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* this could be done more efficiently; name and type should already
+	   be equal */
+	cmp = ldns_rr_compare(rrs->rr, rr);
+	if (cmp < 0) {
+		if (rrs->next) {
+			return ldns_dnssec_rrs_add_rr(rrs->next, rr);
+		} else {
+			new_rrs = ldns_dnssec_rrs_new();
+			new_rrs->rr = rr;
+			rrs->next = new_rrs;
+		}
+	} else if (cmp > 0) {
+		/* put the current old rr in the new next, put the new
+		   rr in the current container */
+		new_rrs = ldns_dnssec_rrs_new();
+		new_rrs->rr = rrs->rr;
+		new_rrs->next = rrs->next;
+		rrs->rr = rr;
+		rrs->next = new_rrs;
+	}
+	/* Silently ignore equal rr's */
+	return LDNS_STATUS_OK;
+}
+
+void
+ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt,
+	       ldns_dnssec_rrs *rrs)
+{
+	if (!rrs) {
+		if ((fmt->flags & LDNS_COMMENT_LAYOUT))
+			fprintf(out, "; <void>");
+	} else {
+		if (rrs->rr) {
+			ldns_rr_print_fmt(out, fmt, rrs->rr);
+		}
+		if (rrs->next) {
+			ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next);
+		}
+	}
+}
+
+void
+ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
+{
+	ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs);
+}
+
+
+ldns_dnssec_rrsets *
+ldns_dnssec_rrsets_new(void)
+{
+	ldns_dnssec_rrsets *new_rrsets;
+	new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
+        if(!new_rrsets) return NULL;
+	new_rrsets->rrs = NULL;
+	new_rrsets->type = 0;
+	new_rrsets->signatures = NULL;
+	new_rrsets->next = NULL;
+	return new_rrsets;
+}
+
+INLINE void
+ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep)
+{
+	if (rrsets) {
+		if (rrsets->rrs) {
+			ldns_dnssec_rrs_free_internal(rrsets->rrs, deep);
+		}
+		if (rrsets->next) {
+			ldns_dnssec_rrsets_free_internal(rrsets->next, deep);
+		}
+		if (rrsets->signatures) {
+			ldns_dnssec_rrs_free_internal(rrsets->signatures, deep);
+		}
+		LDNS_FREE(rrsets);
+	}
+}
+
+void
+ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets)
+{
+	ldns_dnssec_rrsets_free_internal(rrsets, 0);
+}
+
+void
+ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets)
+{
+	ldns_dnssec_rrsets_free_internal(rrsets, 1);
+}
+
+ldns_rr_type
+ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets)
+{
+	if (rrsets) {
+		return rrsets->type;
+	} else {
+		return 0;
+	}
+}
+
+ldns_status
+ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
+					   ldns_rr_type type)
+{
+	if (rrsets) {
+		rrsets->type = type;
+		return LDNS_STATUS_OK;
+	}
+	return LDNS_STATUS_ERR;
+}
+
+static ldns_dnssec_rrsets *
+ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr)
+{
+	ldns_dnssec_rrsets *new_rrsets;
+	ldns_rr_type rr_type;
+	bool rrsig;
+
+	new_rrsets = ldns_dnssec_rrsets_new();
+	rr_type = ldns_rr_get_type(rr);
+	if (rr_type == LDNS_RR_TYPE_RRSIG) {
+		rrsig = true;
+		rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
+	} else {
+		rrsig = false;
+	}
+	if (!rrsig) {
+		new_rrsets->rrs = ldns_dnssec_rrs_new();
+		new_rrsets->rrs->rr = rr;
+	} else {
+		new_rrsets->signatures = ldns_dnssec_rrs_new();
+		new_rrsets->signatures->rr = rr;
+	}
+	new_rrsets->type = rr_type;
+	return new_rrsets;
+}
+
+ldns_status
+ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
+{
+	ldns_dnssec_rrsets *new_rrsets;
+	ldns_rr_type rr_type;
+	bool rrsig = false;
+	ldns_status result = LDNS_STATUS_OK;
+
+	if (!rrsets || !rr) {
+		return LDNS_STATUS_ERR;
+	}
+
+	rr_type = ldns_rr_get_type(rr);
+
+	if (rr_type == LDNS_RR_TYPE_RRSIG) {
+		rrsig = true;
+		rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
+	}
+
+	if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) {
+		if (!rrsig) {
+			rrsets->rrs = ldns_dnssec_rrs_new();
+			rrsets->rrs->rr = rr;
+			rrsets->type = rr_type;
+		} else {
+			rrsets->signatures = ldns_dnssec_rrs_new();
+			rrsets->signatures->rr = rr;
+			rrsets->type = rr_type;
+		}
+		return LDNS_STATUS_OK;
+	}
+
+	if (rr_type > ldns_dnssec_rrsets_type(rrsets)) {
+		if (rrsets->next) {
+			result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr);
+		} else {
+			new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr);
+			rrsets->next = new_rrsets;
+		}
+	} else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) {
+		/* move the current one into the new next, 
+		   replace field of current with data from new rr */
+		new_rrsets = ldns_dnssec_rrsets_new();
+		new_rrsets->rrs = rrsets->rrs;
+		new_rrsets->type = rrsets->type;
+		new_rrsets->signatures = rrsets->signatures;
+		new_rrsets->next = rrsets->next;
+		if (!rrsig) {
+			rrsets->rrs = ldns_dnssec_rrs_new();
+			rrsets->rrs->rr = rr;
+			rrsets->signatures = NULL;
+		} else {
+			rrsets->rrs = NULL;
+			rrsets->signatures = ldns_dnssec_rrs_new();
+			rrsets->signatures->rr = rr;
+		}
+		rrsets->type = rr_type;
+		rrsets->next = new_rrsets;
+	} else {
+		/* equal, add to current rrsets */
+		if (rrsig) {
+			if (rrsets->signatures) {
+				result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr);
+			} else {
+				rrsets->signatures = ldns_dnssec_rrs_new();
+				rrsets->signatures->rr = rr;
+			}
+		} else {
+			if (rrsets->rrs) {
+				result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr);
+			} else {
+				rrsets->rrs = ldns_dnssec_rrs_new();
+				rrsets->rrs->rr = rr;
+			}
+		}
+	}
+
+	return result;
+}
+
+static void
+ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
+		ldns_dnssec_rrsets *rrsets,
+		bool follow,
+		bool show_soa)
+{
+	if (!rrsets) {
+		if ((fmt->flags & LDNS_COMMENT_LAYOUT))
+			fprintf(out, "; <void>\n");
+	} else {
+		if (rrsets->rrs &&
+		    (show_soa ||
+			ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA
+		    )
+		   ) {
+			ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs);
+			if (rrsets->signatures) {
+				ldns_dnssec_rrs_print_fmt(out, fmt, 
+						rrsets->signatures);
+			}
+		}
+		if (follow && rrsets->next) {
+			ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 
+					rrsets->next, follow, show_soa);
+		}
+	}
+}
+
+
+void
+ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt,
+		ldns_dnssec_rrsets *rrsets, 
+		bool follow)
+{
+	ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true);
+}
+
+void
+ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow)
+{
+	ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default, 
+			rrsets, follow);
+}
+
+ldns_dnssec_name *
+ldns_dnssec_name_new(void)
+{
+	ldns_dnssec_name *new_name;
+
+	new_name = LDNS_CALLOC(ldns_dnssec_name, 1);
+	if (!new_name) {
+		return NULL;
+	}
+	/*
+	 * not needed anymore because CALLOC initalizes everything to zero.
+
+	new_name->name = NULL;
+	new_name->rrsets = NULL;
+	new_name->name_alloced = false;
+	new_name->nsec = NULL;
+	new_name->nsec_signatures = NULL;
+
+	new_name->is_glue = false;
+	new_name->hashed_name = NULL;
+
+	 */
+	return new_name;
+}
+
+ldns_dnssec_name *
+ldns_dnssec_name_new_frm_rr(ldns_rr *rr)
+{
+	ldns_dnssec_name *new_name = ldns_dnssec_name_new();
+
+	new_name->name = ldns_rr_owner(rr);
+	if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) {
+		ldns_dnssec_name_free(new_name);
+		return NULL;
+	}
+
+	return new_name;
+}
+
+INLINE void
+ldns_dnssec_name_free_internal(ldns_dnssec_name *name,
+                               int deep)
+{
+	if (name) {
+		if (name->name_alloced) {
+			ldns_rdf_deep_free(name->name);
+		}
+		if (name->rrsets) {
+			ldns_dnssec_rrsets_free_internal(name->rrsets, deep);
+		}
+		if (name->nsec && deep) {
+			ldns_rr_free(name->nsec);
+		}
+		if (name->nsec_signatures) {
+			ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep);
+		}
+		if (name->hashed_name) {
+			if (deep) {
+				ldns_rdf_deep_free(name->hashed_name);
+			}
+		}
+		LDNS_FREE(name);
+	}
+}
+
+void
+ldns_dnssec_name_free(ldns_dnssec_name *name)
+{
+  ldns_dnssec_name_free_internal(name, 0);
+}
+
+void
+ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
+{
+  ldns_dnssec_name_free_internal(name, 1);
+}
+
+ldns_rdf *
+ldns_dnssec_name_name(ldns_dnssec_name *name)
+{
+	if (name) {
+		return name->name;
+	}
+	return NULL;
+}
+
+bool
+ldns_dnssec_name_is_glue(ldns_dnssec_name *name)
+{
+	if (name) {
+		return name->is_glue;
+	}
+	return false;
+}
+
+void
+ldns_dnssec_name_set_name(ldns_dnssec_name *rrset,
+					 ldns_rdf *dname)
+{
+	if (rrset && dname) {
+		rrset->name = dname;
+	}
+}
+
+
+void
+ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
+{
+	if (rrset && nsec) {
+		rrset->nsec = nsec;
+	}
+}
+
+int
+ldns_dnssec_name_cmp(const void *a, const void *b)
+{
+	ldns_dnssec_name *na = (ldns_dnssec_name *) a;
+	ldns_dnssec_name *nb = (ldns_dnssec_name *) b;
+
+	if (na && nb) {
+		return ldns_dname_compare(ldns_dnssec_name_name(na),
+							 ldns_dnssec_name_name(nb));
+	} else if (na) {
+		return 1;
+	} else if (nb) {
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+ldns_status
+ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
+				    ldns_rr *rr)
+{
+	ldns_status result = LDNS_STATUS_OK;
+	ldns_rr_type rr_type;
+	ldns_rr_type typecovered = 0;
+
+	/* special handling for NSEC3 and NSECX covering RRSIGS */
+
+	if (!name || !rr) {
+		return LDNS_STATUS_ERR;
+	}
+
+	rr_type = ldns_rr_get_type(rr);
+
+	if (rr_type == LDNS_RR_TYPE_RRSIG) {
+		typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
+	}
+
+	if (rr_type == LDNS_RR_TYPE_NSEC ||
+	    rr_type == LDNS_RR_TYPE_NSEC3) {
+		/* XX check if is already set (and error?) */
+		name->nsec = rr;
+	} else if (typecovered == LDNS_RR_TYPE_NSEC ||
+			 typecovered == LDNS_RR_TYPE_NSEC3) {
+		if (name->nsec_signatures) {
+			result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr);
+		} else {
+			name->nsec_signatures = ldns_dnssec_rrs_new();
+			name->nsec_signatures->rr = rr;
+		}
+	} else {
+		/* it's a 'normal' RR, add it to the right rrset */
+		if (name->rrsets) {
+			result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
+		} else {
+			name->rrsets = ldns_dnssec_rrsets_new();
+			result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
+		}
+	}
+	return result;
+}
+
+ldns_dnssec_rrsets *
+ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
+					   ldns_rr_type type) {
+	ldns_dnssec_rrsets *result;
+
+	result = name->rrsets;
+	while (result) {
+		if (result->type == type) {
+			return result;
+		} else {
+			result = result->next;
+		}
+	}
+	return NULL;
+}
+
+ldns_dnssec_rrsets *
+ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
+					   ldns_rdf *dname,
+					   ldns_rr_type type)
+{
+	ldns_rbnode_t *node;
+
+	if (!zone || !dname || !zone->names) {
+		return NULL;
+	}
+
+	node = ldns_rbtree_search(zone->names, dname);
+	if (node) {
+		return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data,
+									type);
+	} else {
+		return NULL;
+	}
+}
+
+static void
+ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
+		ldns_dnssec_name *name, 
+		bool show_soa)
+{
+	if (name) {
+		if(name->rrsets) {
+			ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 
+					name->rrsets, true, show_soa);
+		} else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
+			fprintf(out, ";; Empty nonterminal: ");
+			ldns_rdf_print(out, name->name);
+			fprintf(out, "\n");
+		}
+		if(name->nsec) {
+			ldns_rr_print_fmt(out, fmt, name->nsec);
+		}
+		if (name->nsec_signatures) {
+			ldns_dnssec_rrs_print_fmt(out, fmt, 
+					name->nsec_signatures);
+		}
+	} else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
+		fprintf(out, "; <void>\n");
+	}
+}
+
+
+void
+ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt,
+		ldns_dnssec_name *name)
+{
+	ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
+}
+
+void
+ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name)
+{
+	ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name);
+}
+
+
+ldns_dnssec_zone *
+ldns_dnssec_zone_new(void)
+{
+	ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone);
+        if(!zone) return NULL;
+	zone->soa = NULL;
+	zone->names = NULL;
+	zone->hashed_names = NULL;
+	zone->_nsec3params = NULL;
+
+	return zone;
+}
+
+static bool
+rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t)
+{
+	return     ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG
+		&& ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t;
+}
+
+/* When the zone is first read into an list and then inserted into an
+ * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next)
+ * to each other. Because ldns-verify-zone (the only program that uses this
+ * function) uses the rbtree mostly for sequentual walking, this results
+ * in a speed increase (of 15% on linux) because we have less CPU-cache misses.
+ */
+#define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */
+
+static ldns_status
+ldns_dnssec_zone_add_empty_nonterminals_nsec3(
+		ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s);
+
+static void
+ldns_todo_nsec3_ents_node_free(ldns_rbnode_t *node, void *arg) {
+	(void) arg;
+	ldns_rdf_deep_free((ldns_rdf *)node->key);
+	LDNS_FREE(node);
+}
+
+ldns_status
+ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
+	       	uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
+{
+	ldns_rr* cur_rr;
+	size_t i;
+
+	ldns_rdf *my_origin = NULL;
+	ldns_rdf *my_prev = NULL;
+
+	ldns_dnssec_zone *newzone = ldns_dnssec_zone_new();
+	/* NSEC3s may occur before the names they refer to. We must remember
+	   them and add them to the name later on, after the name is read.
+	   We track not yet  matching NSEC3s*n the todo_nsec3s list */
+	ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
+	/* when reading NSEC3s, there is a chance that we encounter nsecs
+	   for empty nonterminals, whose nonterminals we cannot derive yet
+	   because the needed information is to be read later.
+
+	   nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will
+	   hold the NSEC3s that still didn't have a matching name in the
+	   zone tree, even after all names were read.  They can only match
+	   after the zone is equiped with all the empty non terminals. */
+	ldns_rbtree_t todo_nsec3_ents;
+	ldns_rbnode_t *new_node;
+	ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
+
+	ldns_status status;
+
+#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
+	ldns_zone* zone = NULL;
+#else
+	uint32_t  my_ttl = ttl;
+#endif
+
+	ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v);
+
+#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
+	status = ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr);
+	if (status != LDNS_STATUS_OK)
+		goto error;
+#endif
+	if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) {
+		status = LDNS_STATUS_MEM_ERR;
+		goto error;
+	}
+	if (origin) {
+		if (!(my_origin = ldns_rdf_clone(origin))) {
+			status = LDNS_STATUS_MEM_ERR;
+			goto error;
+		}
+		if (!(my_prev   = ldns_rdf_clone(origin))) {
+			status = LDNS_STATUS_MEM_ERR;
+			goto error;
+		}
+	}
+
+#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
+	if (ldns_zone_soa(zone)) {
+		status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone));
+		if (status != LDNS_STATUS_OK)
+			goto error;
+	}
+	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
+		cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
+		status = LDNS_STATUS_OK;
+#else
+	while (!feof(fp)) {
+		status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
+				&my_prev, line_nr);
+
+#endif
+		switch (status) {
+		case LDNS_STATUS_OK:
+
+			status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
+			if (status ==
+				LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) {
+
+				if (rr_is_rrsig_covering(cur_rr,
+							LDNS_RR_TYPE_NSEC3)){
+					ldns_rr_list_push_rr(todo_nsec3_rrsigs,
+							cur_rr);
+				} else {
+					ldns_rr_list_push_rr(todo_nsec3s,
+						       	cur_rr);
+				}
+				status = LDNS_STATUS_OK;
+
+			} else if (status != LDNS_STATUS_OK)
+				goto error;
+
+			break;
+
+
+		case LDNS_STATUS_SYNTAX_EMPTY:	/* empty line was seen */
+		case LDNS_STATUS_SYNTAX_TTL:	/* the ttl was set*/
+		case LDNS_STATUS_SYNTAX_ORIGIN:	/* the origin was set*/
+			status = LDNS_STATUS_OK;
+			break;
+
+		case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
+			status =  LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
+			break;
+
+		default:
+			goto error;
+		}
+	}
+
+	for (i = 0; status == LDNS_STATUS_OK &&
+			i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
+		cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
+		status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
+		if (status == LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) {
+			if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) {
+				status = LDNS_STATUS_MEM_ERR;
+				break;
+			}
+			new_node->key  = ldns_dname_label(ldns_rr_owner(cur_rr), 0);
+			new_node->data = cur_rr;
+			if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) {
+				LDNS_FREE(new_node);
+				status = LDNS_STATUS_MEM_ERR;
+				break;
+			}
+			status = LDNS_STATUS_OK;
+		}
+	}
+	if (todo_nsec3_ents.count > 0)
+		(void) ldns_dnssec_zone_add_empty_nonterminals_nsec3(
+				newzone, &todo_nsec3_ents);
+	for (i = 0; status == LDNS_STATUS_OK &&
+			i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) {
+		cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
+		status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
+	}
+	if (z) {
+		*z = newzone;
+		newzone = NULL;
+	} else {
+		ldns_dnssec_zone_free(newzone);
+	}
+
+error:
+#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
+	if (zone) {
+		ldns_zone_free(zone);
+	}
+#endif
+	ldns_rr_list_free(todo_nsec3_rrsigs);
+	ldns_traverse_postorder(&todo_nsec3_ents,
+			ldns_todo_nsec3_ents_node_free, NULL);
+	ldns_rr_list_free(todo_nsec3s);
+
+	if (my_origin) {
+		ldns_rdf_deep_free(my_origin);
+	}
+	if (my_prev) {
+		ldns_rdf_deep_free(my_prev);
+	}
+	if (newzone) {
+		ldns_dnssec_zone_free(newzone);
+	}
+	return status;
+}
+
+ldns_status
+ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
+		uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
+{
+	return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
+}
+
+static void
+ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
+	(void) arg;
+	ldns_dnssec_name_free((ldns_dnssec_name *)node->data);
+	LDNS_FREE(node);
+}
+
+static void
+ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
+	(void) arg;
+	ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data);
+	LDNS_FREE(node);
+}
+
+void
+ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
+{
+	if (zone) {
+		if (zone->names) {
+			/* destroy all name structures within the tree */
+			ldns_traverse_postorder(zone->names,
+						    ldns_dnssec_name_node_free,
+						    NULL);
+			LDNS_FREE(zone->names);
+		}
+		LDNS_FREE(zone);
+	}
+}
+
+void
+ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
+{
+	if (zone) {
+		if (zone->names) {
+			/* destroy all name structures within the tree */
+			ldns_traverse_postorder(zone->names,
+						    ldns_dnssec_name_node_deep_free,
+						    NULL);
+			LDNS_FREE(zone->names);
+		}
+		LDNS_FREE(zone);
+	}
+}
+
+/* use for dname comparison in tree */
+int
+ldns_dname_compare_v(const void *a, const void *b) {
+	return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
+}
+
+static void
+ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
+		ldns_dnssec_name* name, ldns_rr* nsec3rr);
+
+static void
+ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
+	(void) arg;
+	LDNS_FREE(node);
+}
+
+static void
+ldns_dnssec_zone_hashed_names_from_nsec3(
+		ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
+{
+	ldns_rbnode_t* current_node;
+	ldns_dnssec_name* current_name;
+
+	assert(zone != NULL);
+	assert(nsec3rr != NULL);
+
+	if (zone->hashed_names) {
+		ldns_traverse_postorder(zone->hashed_names,
+				ldns_hashed_names_node_free, NULL);
+		LDNS_FREE(zone->hashed_names);
+	}
+	zone->_nsec3params = nsec3rr;
+
+	/* So this is a NSEC3 zone.
+	* Calculate hashes for all names already in the zone
+	*/
+	zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
+	if (zone->hashed_names == NULL) {
+		return;
+	}
+	for ( current_node  = ldns_rbtree_first(zone->names)
+	    ; current_node != LDNS_RBTREE_NULL
+	    ; current_node  = ldns_rbtree_next(current_node)
+	    ) {
+		current_name = (ldns_dnssec_name *) current_node->data;
+		ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
+
+	}
+}
+
+static void
+ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
+		ldns_dnssec_name* name, ldns_rr* nsec3rr)
+{
+	ldns_rbnode_t* new_node;
+
+	assert(name != NULL);
+	if (! zone->_nsec3params) {
+		if (! nsec3rr) {
+			return;
+		}
+		ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
+
+	} else if (! nsec3rr) {
+		nsec3rr = zone->_nsec3params;
+	}
+	name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
+
+	/* Also store in zone->hashed_names */
+	if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
+
+		new_node->key  = name->hashed_name;
+		new_node->data = name;
+
+		if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
+
+				LDNS_FREE(new_node);
+		}
+	}
+}
+
+
+static ldns_rbnode_t *
+ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
+	ldns_rdf *hashed_name;
+
+	hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
+	if (hashed_name == NULL) {
+		return NULL;
+	}
+	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
+
+		ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
+	}
+	if (zone->hashed_names == NULL) {
+		ldns_rdf_deep_free(hashed_name);
+		return NULL;
+	}
+	return  ldns_rbtree_search(zone->hashed_names, hashed_name);
+}
+
+ldns_status
+ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
+{
+	ldns_status result = LDNS_STATUS_OK;
+	ldns_dnssec_name *cur_name;
+	ldns_rbnode_t *cur_node;
+	ldns_rr_type type_covered = 0;
+
+	if (!zone || !rr) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (!zone->names) {
+		zone->names = ldns_rbtree_create(ldns_dname_compare_v);
+                if(!zone->names) return LDNS_STATUS_MEM_ERR;
+	}
+
+	/* we need the original of the hashed name if this is
+	   an NSEC3, or an RRSIG that covers an NSEC3 */
+	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
+		type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
+	}
+	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
+	    type_covered == LDNS_RR_TYPE_NSEC3) {
+		cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
+		if (!cur_node) {
+			return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND;
+		}
+	} else {
+		cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
+	}
+	if (!cur_node) {
+		/* add */
+		cur_name = ldns_dnssec_name_new_frm_rr(rr);
+                if(!cur_name) return LDNS_STATUS_MEM_ERR;
+		cur_node = LDNS_MALLOC(ldns_rbnode_t);
+                if(!cur_node) {
+                        ldns_dnssec_name_free(cur_name);
+                        return LDNS_STATUS_MEM_ERR;
+                }
+		cur_node->key = ldns_rr_owner(rr);
+		cur_node->data = cur_name;
+		(void)ldns_rbtree_insert(zone->names, cur_node);
+		ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
+	} else {
+		cur_name = (ldns_dnssec_name *) cur_node->data;
+		result = ldns_dnssec_name_add_rr(cur_name, rr);
+	}
+	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
+		zone->soa = cur_name;
+	}
+	return result;
+}
+
+void
+ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
+		ldns_rbtree_t *tree, 
+		bool print_soa)
+{
+	ldns_rbnode_t *node;
+	ldns_dnssec_name *name;
+
+	node = ldns_rbtree_first(tree);
+	while (node != LDNS_RBTREE_NULL) {
+		name = (ldns_dnssec_name *) node->data;
+		ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
+		if ((fmt->flags & LDNS_COMMENT_LAYOUT))
+			fprintf(out, ";\n");
+		node = ldns_rbtree_next(node);
+	}
+}
+
+void
+ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
+{
+	ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default,
+		       tree, print_soa);
+}
+
+void
+ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt,
+	       ldns_dnssec_zone *zone)
+{
+	if (zone) {
+		if (zone->soa) {
+			if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
+				fprintf(out, ";; Zone: ");
+				ldns_rdf_print(out, ldns_dnssec_name_name(
+							zone->soa));
+				fprintf(out, "\n;\n");
+			}
+			ldns_dnssec_rrsets_print_fmt(out, fmt,
+					ldns_dnssec_name_find_rrset(
+						zone->soa, 
+						LDNS_RR_TYPE_SOA), 
+					false);
+			if ((fmt->flags & LDNS_COMMENT_LAYOUT))
+				fprintf(out, ";\n");
+		}
+
+		if (zone->names) {
+			ldns_dnssec_zone_names_print_fmt(out, fmt, 
+					zone->names, false);
+		}
+	}
+}
+
+void
+ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
+{
+	ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone);
+}
+
+static ldns_status
+ldns_dnssec_zone_add_empty_nonterminals_nsec3(
+		ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s)
+{
+	ldns_dnssec_name *new_name;
+	ldns_rdf *cur_name;
+	ldns_rdf *next_name;
+	ldns_rbnode_t *cur_node, *next_node, *new_node;
+
+	/* for the detection */
+	uint16_t i, cur_label_count, next_label_count;
+	uint16_t soa_label_count = 0;
+	ldns_rdf *l1, *l2;
+	int lpos;
+
+	if (!zone) {
+		return LDNS_STATUS_ERR;
+	}
+	if (zone->soa && zone->soa->name) {
+		soa_label_count = ldns_dname_label_count(zone->soa->name);
+	}
+	
+	cur_node = ldns_rbtree_first(zone->names);
+	while (cur_node != LDNS_RBTREE_NULL) {
+		next_node = ldns_rbtree_next(cur_node);
+		
+		/* skip glue */
+		while (next_node != LDNS_RBTREE_NULL && 
+		       next_node->data &&
+		       ((ldns_dnssec_name *)next_node->data)->is_glue
+		) {
+			next_node = ldns_rbtree_next(next_node);
+		}
+
+		if (next_node == LDNS_RBTREE_NULL) {
+			next_node = ldns_rbtree_first(zone->names);
+		}
+		if (! cur_node->data || ! next_node->data) {
+			return LDNS_STATUS_ERR;
+		}
+		cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
+		next_name = ((ldns_dnssec_name *)next_node->data)->name;
+		cur_label_count = ldns_dname_label_count(cur_name);
+		next_label_count = ldns_dname_label_count(next_name);
+
+		/* Since the names are in canonical order, we can
+		 * recognize empty non-terminals by their labels;
+		 * every label after the first one on the next owner
+		 * name is a non-terminal if it either does not exist
+		 * in the current name or is different from the same
+		 * label in the current name (counting from the end)
+		 */
+		for (i = 1; i < next_label_count - soa_label_count; i++) {
+			lpos = (int)cur_label_count - (int)next_label_count + (int)i;
+			if (lpos >= 0) {
+				l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
+			} else {
+				l1 = NULL;
+			}
+			l2 = ldns_dname_clone_from(next_name, i);
+
+			if (!l1 || ldns_dname_compare(l1, l2) != 0) {
+				/* We have an empty nonterminal, add it to the
+				 * tree
+				 */
+				ldns_rbnode_t *node = NULL;
+				ldns_rdf *ent_name;
+
+				if (!(ent_name = ldns_dname_clone_from(
+						next_name, i)))
+					return LDNS_STATUS_MEM_ERR;
+
+				if (nsec3s && zone->_nsec3params) {
+					ldns_rdf *ent_hashed_name;
+
+					if (!(ent_hashed_name =
+					    ldns_nsec3_hash_name_frm_nsec3(
+							zone->_nsec3params,
+							ent_name)))
+						return LDNS_STATUS_MEM_ERR;
+					node = ldns_rbtree_search(nsec3s, 
+							ent_hashed_name);
+					if (!node) {
+						ldns_rdf_deep_free(l1);
+						ldns_rdf_deep_free(l2);
+						continue;
+					}
+				}
+				new_name = ldns_dnssec_name_new();
+				if (!new_name) {
+					return LDNS_STATUS_MEM_ERR;
+				}
+				new_name->name = ent_name;
+				if (!new_name->name) {
+					ldns_dnssec_name_free(new_name);
+					return LDNS_STATUS_MEM_ERR;
+				}
+				new_name->name_alloced = true;
+				new_node = LDNS_MALLOC(ldns_rbnode_t);
+				if (!new_node) {
+					ldns_dnssec_name_free(new_name);
+					return LDNS_STATUS_MEM_ERR;
+				}
+				new_node->key = new_name->name;
+				new_node->data = new_name;
+				(void)ldns_rbtree_insert(zone->names, new_node);
+				ldns_dnssec_name_make_hashed_name(
+						zone, new_name, NULL);
+				if (node)
+					(void) ldns_dnssec_zone_add_rr(zone,
+							(ldns_rr *)node->data);
+			}
+			ldns_rdf_deep_free(l1);
+			ldns_rdf_deep_free(l2);
+		}
+		
+		/* we might have inserted a new node after
+		 * the current one so we can't just use next()
+		 */
+		if (next_node != ldns_rbtree_first(zone->names)) {
+			cur_node = next_node;
+		} else {
+			cur_node = LDNS_RBTREE_NULL;
+		}
+	}
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
+{
+	return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL);
+}
+
+bool
+ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone)
+{
+	ldns_rr* nsec3;
+	ldns_rbnode_t* node;
+
+	if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) {
+		node = ldns_rbtree_first(zone->names);
+		while (node != LDNS_RBTREE_NULL) {
+			nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
+			if (nsec3 &&ldns_rr_get_type(nsec3) 
+					== LDNS_RR_TYPE_NSEC3 &&
+					ldns_nsec3_optout(nsec3)) {
+				return true;
+			}
+			node = ldns_rbtree_next(node);
+		}
+	}
+	return false;
+}
diff --git a/ldns/src/duration.c b/ldns/src/duration.c
new file mode 100644
index 0000000..6d0a388
--- /dev/null
+++ b/ldns/src/duration.c
@@ -0,0 +1,354 @@
+/*
+ * $Id: duration.c 4518 2011-02-24 15:39:09Z matthijs $
+ *
+ * Copyright (c) 2009 NLNet Labs. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ *
+ * This file is copied from the OpenDNSSEC source repository
+ * and only slightly adapted to make it fit.
+ */
+
+/**
+ *
+ * Durations.
+ */
+
+#include <ldns/config.h>
+#include <ldns/duration.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+
+/**
+ * Create a new 'instant' duration.
+ *
+ */
+ldns_duration_type*
+ldns_duration_create(void)
+{
+    ldns_duration_type* duration;
+
+    duration = malloc(sizeof(ldns_duration_type));
+    if (!duration) {
+        return NULL;
+    }
+    duration->years = 0;
+    duration->months = 0;
+    duration->weeks = 0;
+    duration->days = 0;
+    duration->hours = 0;
+    duration->minutes = 0;
+    duration->seconds = 0;
+    return duration;
+}
+
+
+/**
+ * Compare durations.
+ *
+ */
+int
+ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2)
+{
+    if (!d1 && !d2) {
+        return 0;
+    }
+    if (!d1 || !d2) {
+        return d1?-1:1;
+    }
+
+    if (d1->years != d2->years) {
+        return (int) (d1->years - d2->years);
+    }
+    if (d1->months != d2->months) {
+        return (int) (d1->months - d2->months);
+    }
+    if (d1->weeks != d2->weeks) {
+        return (int) (d1->weeks - d2->weeks);
+    }
+    if (d1->days != d2->days) {
+        return (int) (d1->days - d2->days);
+    }
+    if (d1->hours != d2->hours) {
+        return (int) (d1->hours - d2->hours);
+    }
+    if (d1->minutes != d2->minutes) {
+        return (int) (d1->minutes - d2->minutes);
+    }
+    if (d1->seconds != d2->seconds) {
+        return (int) (d1->seconds - d2->seconds);
+    }
+
+    return 0;
+}
+
+
+/**
+ * Create a duration from string.
+ *
+ */
+ldns_duration_type*
+ldns_duration_create_from_string(const char* str)
+{
+    ldns_duration_type* duration = ldns_duration_create();
+    char* P, *X, *T, *W;
+    int not_weeks = 0;
+
+    if (!duration) {
+        return NULL;
+    }
+    if (!str) {
+        return duration;
+    }
+
+    P = strchr(str, 'P');
+    if (!P) {
+	ldns_duration_cleanup(duration);
+        return NULL;
+    }
+
+    T = strchr(str, 'T');
+    X = strchr(str, 'Y');
+    if (X) {
+        duration->years = (time_t) atoi(str+1);
+        str = X;
+        not_weeks = 1;
+    }
+    X = strchr(str, 'M');
+    if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) {
+        duration->months = (time_t) atoi(str+1);
+        str = X;
+        not_weeks = 1;
+    }
+    X = strchr(str, 'D');
+    if (X) {
+        duration->days = (time_t) atoi(str+1);
+        str = X;
+        not_weeks = 1;
+    }
+    if (T) {
+        str = T;
+        not_weeks = 1;
+    }
+    X = strchr(str, 'H');
+    if (X && T) {
+        duration->hours = (time_t) atoi(str+1);
+        str = X;
+        not_weeks = 1;
+    }
+    X = strrchr(str, 'M');
+    if (X && T && (size_t) (X-P) > (size_t) (T-P)) {
+        duration->minutes = (time_t) atoi(str+1);
+        str = X;
+        not_weeks = 1;
+    }
+    X = strchr(str, 'S');
+    if (X && T) {
+        duration->seconds = (time_t) atoi(str+1);
+        str = X;
+        not_weeks = 1;
+    }
+
+    W = strchr(str, 'W');
+    if (W) {
+        if (not_weeks) {
+            ldns_duration_cleanup(duration);
+            return NULL;
+        } else {
+            duration->weeks = (time_t) atoi(str+1);
+            str = W;
+        }
+    }
+    return duration;
+}
+
+
+/**
+ * Get the number of digits in a number.
+ *
+ */
+static size_t
+digits_in_number(time_t duration)
+{
+    uint32_t period = (uint32_t) duration;
+    size_t count = 0;
+
+    while (period > 0) {
+        count++;
+        period /= 10;
+    }
+    return count;
+}
+
+
+/**
+ * Convert a duration to a string.
+ *
+ */
+char*
+ldns_duration2string(ldns_duration_type* duration)
+{
+    char* str = NULL, *num = NULL;
+    size_t count = 2;
+    int T = 0;
+
+    if (!duration) {
+        return NULL;
+    }
+
+    if (duration->years > 0) {
+        count = count + 1 + digits_in_number(duration->years);
+    }
+    if (duration->months > 0) {
+        count = count + 1 + digits_in_number(duration->months);
+    }
+    if (duration->weeks > 0) {
+        count = count + 1 + digits_in_number(duration->weeks);
+    }
+    if (duration->days > 0) {
+        count = count + 1 + digits_in_number(duration->days);
+    }
+    if (duration->hours > 0) {
+        count = count + 1 + digits_in_number(duration->hours);
+        T = 1;
+    }
+    if (duration->minutes > 0) {
+        count = count + 1 + digits_in_number(duration->minutes);
+        T = 1;
+    }
+    if (duration->seconds > 0) {
+        count = count + 1 + digits_in_number(duration->seconds);
+        T = 1;
+    }
+    if (T) {
+        count++;
+    }
+
+    str = (char*) calloc(count, sizeof(char));
+    str[0] = 'P';
+    str[1] = '\0';
+
+    if (duration->years > 0) {
+        count = digits_in_number(duration->years);
+        num = (char*) calloc(count+2, sizeof(char));
+        snprintf(num, count+2, "%uY", (unsigned int) duration->years);
+        str = strncat(str, num, count+2);
+        free((void*) num);
+    }
+    if (duration->months > 0) {
+        count = digits_in_number(duration->months);
+        num = (char*) calloc(count+2, sizeof(char));
+        snprintf(num, count+2, "%uM", (unsigned int) duration->months);
+        str = strncat(str, num, count+2);
+        free((void*) num);
+    }
+    if (duration->weeks > 0) {
+        count = digits_in_number(duration->weeks);
+        num = (char*) calloc(count+2, sizeof(char));
+        snprintf(num, count+2, "%uW", (unsigned int) duration->weeks);
+        str = strncat(str, num, count+2);
+        free((void*) num);
+    }
+    if (duration->days > 0) {
+        count = digits_in_number(duration->days);
+        num = (char*) calloc(count+2, sizeof(char));
+        snprintf(num, count+2, "%uD", (unsigned int) duration->days);
+        str = strncat(str, num, count+2);
+        free((void*) num);
+    }
+    if (T) {
+        str = strncat(str, "T", 1);
+    }
+    if (duration->hours > 0) {
+        count = digits_in_number(duration->hours);
+        num = (char*) calloc(count+2, sizeof(char));
+        snprintf(num, count+2, "%uH", (unsigned int) duration->hours);
+        str = strncat(str, num, count+2);
+        free((void*) num);
+    }
+    if (duration->minutes > 0) {
+        count = digits_in_number(duration->minutes);
+        num = (char*) calloc(count+2, sizeof(char));
+        snprintf(num, count+2, "%uM", (unsigned int) duration->minutes);
+        str = strncat(str, num, count+2);
+        free((void*) num);
+    }
+    if (duration->seconds > 0) {
+        count = digits_in_number(duration->seconds);
+        num = (char*) calloc(count+2, sizeof(char));
+        snprintf(num, count+2, "%uS", (unsigned int) duration->seconds);
+        str = strncat(str, num, count+2);
+        free((void*) num);
+    }
+    return str;
+}
+
+
+/**
+ * Convert a duration to a time.
+ *
+ */
+time_t
+ldns_duration2time(ldns_duration_type* duration)
+{
+    time_t period = 0;
+
+    if (duration) {
+        period += (duration->seconds);
+        period += (duration->minutes)*60;
+        period += (duration->hours)*3600;
+        period += (duration->days)*86400;
+        period += (duration->weeks)*86400*7;
+        period += (duration->months)*86400*31;
+        period += (duration->years)*86400*365;
+
+        /* [TODO] calculate correct number of days in this month/year */
+	/*
+        if (duration->months || duration->years) {
+        }
+	*/
+    }
+    return period;
+}
+
+
+/**
+ * Clean up duration.
+ *
+ */
+void
+ldns_duration_cleanup(ldns_duration_type* duration)
+{
+    if (!duration) {
+        return;
+    }
+    free(duration);
+    return;
+}
diff --git a/ldns/src/error.c b/ldns/src/error.c
new file mode 100644
index 0000000..82ea61a
--- /dev/null
+++ b/ldns/src/error.c
@@ -0,0 +1,160 @@
+/*
+ * a error2str function to make sense of all the
+ * error codes we have laying ardoun
+ *
+ * a Net::DNS like library for C
+ * LibDNS Team @ NLnet Labs
+ * (c) NLnet Labs, 2005-2006
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+ldns_lookup_table ldns_error_str[] = {
+	{ LDNS_STATUS_OK, "All OK" },
+	{ LDNS_STATUS_EMPTY_LABEL, "Empty label" },
+        { LDNS_STATUS_LABEL_OVERFLOW, "Label length overflow" },
+        { LDNS_STATUS_DOMAINNAME_OVERFLOW, "Domainname length overflow" },
+        { LDNS_STATUS_DOMAINNAME_UNDERFLOW, "Domainname length underflow (zero length)" },
+        { LDNS_STATUS_DDD_OVERFLOW, "\\DDD sequence overflow (>255)" },
+        { LDNS_STATUS_PACKET_OVERFLOW, "Packet size overflow" },
+        { LDNS_STATUS_INVALID_POINTER, "Invalid compression pointer" },
+        { LDNS_STATUS_MEM_ERR, "General memory error" },
+        { LDNS_STATUS_INTERNAL_ERR, "Internal error, this should not happen" },
+        { LDNS_STATUS_SSL_ERR, "Error in SSL library" },
+        { LDNS_STATUS_ERR, "General LDNS error" },
+        { LDNS_STATUS_INVALID_INT, "Conversion error, integer expected" },
+        { LDNS_STATUS_INVALID_IP4, "Conversion error, ip4 addr expected" },
+        { LDNS_STATUS_INVALID_IP6, "Conversion error, ip6 addr expected" },
+        { LDNS_STATUS_INVALID_STR, "Conversion error, string expected" },
+	{ LDNS_STATUS_INVALID_B32_EXT, "Conversion error, b32 ext encoding expected" },
+        { LDNS_STATUS_INVALID_B64, "Conversion error, b64 encoding expected" },
+        { LDNS_STATUS_INVALID_HEX, "Conversion error, hex encoding expected" },
+        { LDNS_STATUS_INVALID_TIME, "Conversion error, time encoding expected" },
+        { LDNS_STATUS_NETWORK_ERR, "Could not send or receive, because of network error" },
+        { LDNS_STATUS_ADDRESS_ERR, "Could not start AXFR, because of address error" },
+        { LDNS_STATUS_FILE_ERR, "Could not open the files" },
+        { LDNS_STATUS_UNKNOWN_INET, "Uknown address family" },
+        { LDNS_STATUS_NOT_IMPL, "This function is not implemented (yet), please notify the developers - or not..." },
+	{ LDNS_STATUS_NULL, "Supplied value pointer null" },
+        { LDNS_STATUS_CRYPTO_UNKNOWN_ALGO, "Unknown cryptographic algorithm" },
+        { LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL, "Cryptographic algorithm not implemented" },
+        { LDNS_STATUS_CRYPTO_NO_RRSIG, "No DNSSEC signature(s)" },
+        { LDNS_STATUS_CRYPTO_NO_DNSKEY, "No DNSSEC public key(s)" },
+        { LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR, "The signature does not cover this RRset" },
+        { LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY, "No signatures found for trusted DNSSEC public key(s)" },
+        { LDNS_STATUS_CRYPTO_NO_DS, "No DS record(s)" },
+        { LDNS_STATUS_CRYPTO_NO_TRUSTED_DS, "Could not validate DS record(s)" },
+        { LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY, "No keys with the keytag and algorithm from the RRSIG found" },
+        { LDNS_STATUS_CRYPTO_VALIDATED, "Valid DNSSEC signature" },
+        { LDNS_STATUS_CRYPTO_BOGUS, "Bogus DNSSEC signature" },
+        { LDNS_STATUS_CRYPTO_SIG_EXPIRED, "DNSSEC signature has expired" },
+        { LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED, "DNSSEC signature not incepted yet" },
+	{ LDNS_STATUS_CRYPTO_TSIG_BOGUS, "Bogus TSIG signature" },
+	{ LDNS_STATUS_CRYPTO_TSIG_ERR, "Could not create TSIG signature" },
+        { LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION, "DNSSEC signature has expiration date earlier than inception date" },
+	{ LDNS_STATUS_ENGINE_KEY_NOT_LOADED, "Unable to load private key from engine" },
+        { LDNS_STATUS_NSEC3_ERR, "Error in NSEC3 denial of existence proof" },
+	{ LDNS_STATUS_RES_NO_NS, "No (valid) nameservers defined in the resolver" },
+	{ LDNS_STATUS_RES_QUERY, "No correct query given to resolver" },
+	{ LDNS_STATUS_WIRE_INCOMPLETE_HEADER, "header section incomplete" },
+	{ LDNS_STATUS_WIRE_INCOMPLETE_QUESTION, "question section incomplete" },
+	{ LDNS_STATUS_WIRE_INCOMPLETE_ANSWER, "answer section incomplete" },
+	{ LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY, "authority section incomplete" },
+	{ LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL, "additional section incomplete" },
+	{ LDNS_STATUS_NO_DATA, "No data" },
+	{ LDNS_STATUS_EXISTS_ERR, "Element already exists" },
+	{ LDNS_STATUS_CERT_BAD_ALGORITHM, "Bad algorithm type for CERT record" },
+	{ LDNS_STATUS_SYNTAX_TYPE_ERR, "Syntax error, could not parse the RR's type" },
+	{ LDNS_STATUS_SYNTAX_CLASS_ERR, "Syntax error, could not parse the RR's class" },
+	{ LDNS_STATUS_SYNTAX_TTL_ERR, "Syntax error, could not parse the RR's TTL" },
+	{ LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL, "Syntax error, $INCLUDE not implemented" },
+	{ LDNS_STATUS_SYNTAX_RDATA_ERR, "Syntax error, could not parse the RR's rdata" },
+	{ LDNS_STATUS_SYNTAX_DNAME_ERR, "Syntax error, could not parse the RR's dname(s)" },
+	{ LDNS_STATUS_SYNTAX_VERSION_ERR, "Syntax error, version mismatch" },
+	{ LDNS_STATUS_SYNTAX_ALG_ERR, "Syntax error, algorithm unknown or non parseable" },
+	{ LDNS_STATUS_SYNTAX_KEYWORD_ERR, "Syntax error, unknown keyword in input" },
+	{ LDNS_STATUS_SYNTAX_ERR, "Syntax error, could not parse the RR" },
+	{ LDNS_STATUS_SYNTAX_EMPTY, "Empty line was returned" },
+	{ LDNS_STATUS_SYNTAX_TTL, "$TTL directive was seen in the zone" },
+	{ LDNS_STATUS_SYNTAX_ORIGIN, "$ORIGIN directive was seen in the zone" },
+	{ LDNS_STATUS_SYNTAX_INCLUDE, "$INCLUDE directive was seen in the zone" },
+	{ LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW, "Iterations count for NSEC3 record higher than maximum" },
+	{ LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR, "Syntax error, value expected" },
+	{ LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer value too large" },
+	{ LDNS_STATUS_SYNTAX_BAD_ESCAPE, "Syntax error, bad escape sequence" },
+	{ LDNS_STATUS_SOCKET_ERROR, "Error creating socket" },
+	{ LDNS_STATUS_DNSSEC_EXISTENCE_DENIED, "Existence denied by NSEC" },
+	{ LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED, "RR not covered by the given NSEC RRs" },
+	{ LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED, "wildcard not covered by the given NSEC RRs" },
+	{ LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND, "original of NSEC3 hashed name could not be found" },
+	{ LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG, "The RRSIG has to few rdata fields" },
+	{ LDNS_STATUS_MISSING_RDATA_FIELDS_KEY, "The DNSKEY has to few rdata fields" },
+	{ LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN, 
+		"DNSSEC signature will expire too soon" },
+	{ LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN,
+		"DNSSEC signature not incepted long enough" },
+	{ LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE,
+		"Unknown TLSA Certificate Usage" },
+	{ LDNS_STATUS_DANE_UNKNOWN_SELECTOR, "Unknown TLSA Selector" },
+	{ LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE,
+		"Unknown TLSA Matching Type" },
+	{ LDNS_STATUS_DANE_UNKNOWN_PROTOCOL,
+		"Unknown protocol. Only IPv4 and IPv6 are understood" },
+	{ LDNS_STATUS_DANE_UNKNOWN_TRANSPORT,
+		"Unknown transport. Should be one of {tcp, udp, sctp}" },
+	{ LDNS_STATUS_DANE_MISSING_EXTRA_CERTS,  /* Trust anchor assertion */
+		"More than one certificate should be provided" },
+	{ LDNS_STATUS_DANE_EXTRA_CERTS_NOT_USED, /* Trust anchor assertion */
+		"Non of the extra certificates is used to sign the first" },
+	{ LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE,   /* Trust anchor assertion */
+		"The offset was out of range" },
+	{ LDNS_STATUS_DANE_INSECURE,             /* Unused by library */
+		"The queried resource records were insecure" },
+	{ LDNS_STATUS_DANE_BOGUS,             /* Unused by library */
+		"The queried resource records were bogus" },
+	{ LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
+		"The TLSA record(s) "
+		"did not match with the server certificate (chain)" },
+	{ LDNS_STATUS_DANE_NON_CA_CERTIFICATE,
+		"The certificate was not a CA certificate" },
+	{ LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE,
+		"Could not PKIX validate" },
+	{ LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR,
+		"The validation path "
+		"did not end in a self-signed certificate" },
+        { LDNS_STATUS_INVALID_ILNP64, 
+		"Conversion error, 4 colon separated hex numbers expected" },
+        { LDNS_STATUS_INVALID_EUI48, 
+		"Conversion error, 6 two character hex numbers "
+		"separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx" },
+        { LDNS_STATUS_INVALID_EUI64, 
+		"Conversion error, 8 two character hex numbers "
+		"separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx-xx-xx" },
+	{ LDNS_STATUS_WIRE_RDATA_ERR, "invalid rdata in wire format" },
+        { LDNS_STATUS_INVALID_TAG, 
+		"Conversion error, a non-zero sequence of US-ASCII letters "
+		"and numbers in lower case expected" },
+        { LDNS_STATUS_TYPE_NOT_IN_BITMAP, 
+		"The RR type bitmap rdata field did not have "
+		"a bit reserved for the specific RR type" },
+        { LDNS_STATUS_INVALID_RDF_TYPE, 
+		"The rdata field was not of the expected type" },
+        { LDNS_STATUS_RDATA_OVERFLOW, "Rdata size overflow" },
+	{ 0, NULL }
+};
+
+const char *
+ldns_get_errorstr_by_id(ldns_status err)
+{
+        ldns_lookup_table *lt;
+
+        lt = ldns_lookup_by_id(ldns_error_str, err);
+
+        if (lt) {
+                return lt->name;
+        }
+        return NULL;
+}
diff --git a/ldns/src/higher.c b/ldns/src/higher.c
new file mode 100644
index 0000000..8ce86a4
--- /dev/null
+++ b/ldns/src/higher.c
@@ -0,0 +1,344 @@
+/*
+ * higher.c
+ *
+ * Specify some higher level functions that would
+ * be usefull to would be developers
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#ifdef HAVE_SSL
+#include <openssl/ssl.h>
+#include <openssl/sha.h>
+#endif /* HAVE_SSL */
+
+ldns_rr_list *
+ldns_get_rr_list_addr_by_name(ldns_resolver *res, ldns_rdf *name, ldns_rr_class c, 
+		uint16_t flags)
+{
+	ldns_pkt *pkt;
+	ldns_rr_list *aaaa;
+	ldns_rr_list *a;
+	ldns_rr_list *result = NULL;
+	ldns_rr_list *hostsfilenames;
+	size_t i;
+	uint8_t ip6;
+
+	a = NULL; 
+	aaaa = NULL; 
+	result = NULL;
+
+	if (!res) {
+		return NULL;
+	}
+	if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
+		return NULL;
+	}
+
+	ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
+					 what was there */
+
+	ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
+	
+	hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
+	for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
+		if (ldns_rdf_compare(name, 
+					ldns_rr_owner(ldns_rr_list_rr(hostsfilenames, 
+							i))) == 0) {
+			if (!result) {
+				result = ldns_rr_list_new();
+			}
+			ldns_rr_list_push_rr(result, 
+					ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
+		}
+	}
+	ldns_rr_list_deep_free(hostsfilenames);
+
+	if (result) {
+		return result;
+	}
+
+	/* add the RD flags, because we want an answer */
+	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
+	if (pkt) {
+		/* extract the data we need */
+		aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA, 
+			LDNS_SECTION_ANSWER);
+		ldns_pkt_free(pkt);
+	} 
+
+	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
+	if (pkt) {
+		/* extract the data we need */
+		a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
+		ldns_pkt_free(pkt);
+	} 
+	ldns_resolver_set_ip6(res, ip6);
+
+	if (aaaa && a) {
+		result = ldns_rr_list_cat_clone(aaaa, a);
+		ldns_rr_list_deep_free(aaaa);
+		ldns_rr_list_deep_free(a);
+		return result;
+	}
+	
+	if (aaaa) {
+		result = ldns_rr_list_clone(aaaa);
+	}
+	
+	if (a) {
+		result = ldns_rr_list_clone(a);
+	}
+
+	ldns_rr_list_deep_free(aaaa);
+	ldns_rr_list_deep_free(a);
+	return result;
+}
+
+ldns_rr_list *
+ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class c, 
+		uint16_t flags)
+{
+	ldns_pkt *pkt;
+	ldns_rr_list *names;
+	ldns_rdf *name;
+
+	names = NULL;
+
+	if (!res || !addr) {
+		return NULL;
+	}
+
+	if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
+			ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
+		return NULL;
+	}
+
+	name = ldns_rdf_address_reverse(addr);
+	
+	/* add the RD flags, because we want an answer */
+	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
+	ldns_rdf_deep_free(name);
+	if (pkt) {
+		/* extract the data we need */
+		names = ldns_pkt_rr_list_by_type(pkt, 
+				LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
+		ldns_pkt_free(pkt);
+	}
+	return names;
+}
+
+/* read a line, put it in a buffer, parse the buffer */
+ldns_rr_list *
+ldns_get_rr_list_hosts_frm_fp(FILE *fp)
+{
+	return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
+}
+
+ldns_rr_list *
+ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
+{
+	ssize_t i, j;
+	size_t cnt;
+	char *line;
+	char *word;
+	char *addr;
+	char *rr_str;
+	ldns_buffer *linebuf;
+	ldns_rr *rr;
+	ldns_rr_list *list;
+	ldns_rdf *tmp;
+	bool ip6;
+	ldns_status parse_result;
+
+	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
+	word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
+	addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
+	rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
+	ip6 = false;
+	list = ldns_rr_list_new();
+	rr = NULL;
+	if(!line || !word || !addr || !rr_str || !list) {
+		LDNS_FREE(line);
+		LDNS_FREE(word);
+		LDNS_FREE(addr);
+		LDNS_FREE(rr_str);
+		ldns_rr_list_free(list);
+		return NULL;
+	}
+
+	for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
+			i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
+		/* # is comment */
+		if (line[0] == '#') {
+			continue;
+		}
+		/* put it in a buffer for further processing */
+		linebuf = LDNS_MALLOC(ldns_buffer);
+		if(!linebuf) {
+			LDNS_FREE(line);
+			LDNS_FREE(word);
+			LDNS_FREE(addr);
+			LDNS_FREE(rr_str);
+			ldns_rr_list_deep_free(list);
+			return NULL;
+		}
+
+		ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
+		for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
+				j > 0;
+				j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
+			if (cnt == 0) {
+				/* the address */
+				if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, 
+								word))) {
+					/* ip6 */
+					ldns_rdf_deep_free(tmp);
+					ip6 = true;
+				} else {
+					if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, 
+									word))) {
+						/* ip4 */
+						ldns_rdf_deep_free(tmp);
+						ip6 = false;
+					} else {
+						/* kaput */
+						break;
+					}
+				}
+				(void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
+			} else {
+				/* la al la la */
+				if (ip6) {
+					snprintf(rr_str, LDNS_MAX_LINELEN, 
+						"%s IN AAAA %s", word, addr);
+				} else {
+					snprintf(rr_str, LDNS_MAX_LINELEN, 
+						"%s IN A %s", word, addr);
+				}
+				parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
+				if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
+					ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
+				}
+				ldns_rr_free(rr);
+			}
+		}
+		ldns_buffer_free(linebuf);
+	}
+	LDNS_FREE(line);
+	LDNS_FREE(word);
+	LDNS_FREE(addr);
+	LDNS_FREE(rr_str);
+	return list;
+}
+
+ldns_rr_list *
+ldns_get_rr_list_hosts_frm_file(char *filename)
+{
+	ldns_rr_list *names;
+	FILE *fp;
+
+	if (!filename) {
+                fp = fopen(LDNS_RESOLV_HOSTS, "r");
+        
+        } else {
+                fp = fopen(filename, "r");
+        }
+        if (!fp) {
+                return NULL;
+        }
+
+	names = ldns_get_rr_list_hosts_frm_fp(fp);
+	fclose(fp);
+	return names;
+}
+
+uint16_t
+ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c, 
+		ldns_rr_list **ret)
+{
+	ldns_rdf_type t;
+	uint16_t names_found;
+	ldns_resolver *r;
+	ldns_status s;
+
+	t = ldns_rdf_get_type(node);
+	names_found = 0;
+	r = res;
+
+	if (res == NULL) {
+		/* prepare a new resolver, using /etc/resolv.conf as a guide  */
+		s = ldns_resolver_new_frm_file(&r, NULL);
+		if (s != LDNS_STATUS_OK) {
+			return 0;
+		} 
+	}
+
+	if (t == LDNS_RDF_TYPE_DNAME) {
+		/* we're asked to query for a name */
+		*ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
+		names_found = ldns_rr_list_rr_count(*ret);
+	}
+
+	if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
+		/* an address */
+		*ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
+		names_found = ldns_rr_list_rr_count(*ret);
+	}
+
+	if (res == NULL) {
+		ldns_resolver_deep_free(r);
+	}
+	
+	return names_found;
+}
+
+bool
+ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
+{
+	switch (ldns_rr_get_type(nsec)) {
+	case LDNS_RR_TYPE_NSEC	: if (ldns_rr_rd_count(nsec) < 2) {
+					  return false;
+				  }
+				  return ldns_nsec_bitmap_covers_type(
+						  ldns_rr_rdf(nsec, 1), t);
+
+	case LDNS_RR_TYPE_NSEC3	: if (ldns_rr_rd_count(nsec) < 6) {
+					  return false;
+				  }
+				  return ldns_nsec_bitmap_covers_type(
+						  ldns_rr_rdf(nsec, 5), t);
+
+	default			: return false;
+	}
+}
+
+void
+ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
+{
+	int16_t rdf;
+	ldns_rdf *rd;
+	va_list va_rdf;
+	va_start(va_rdf, rdfnum);
+
+	for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int)) 
+	{
+		rd = ldns_rr_rdf(r, rdf);
+		if (!rd) {
+			continue;
+		} else {
+			ldns_rdf_print(fp, rd);
+			fprintf(fp, " "); /* not sure if we want to do this */
+		}
+	}
+	va_end(va_rdf);
+}
+
diff --git a/ldns/src/host2str.c b/ldns/src/host2str.c
new file mode 100644
index 0000000..3445254
--- /dev/null
+++ b/ldns/src/host2str.c
@@ -0,0 +1,2635 @@
+/*
+ * host2str.c
+ *
+ * conversion routines from the host format
+ * to the presentation format (strings)
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <limits.h>
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#include <time.h>
+#include <sys/time.h>
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
+/* lookup tables for standard DNS stuff  */
+
+/* Taken from RFC 2535, section 7.  */
+ldns_lookup_table ldns_algorithms[] = {
+        { LDNS_RSAMD5, "RSAMD5" },
+        { LDNS_DH, "DH" },
+        { LDNS_DSA, "DSA" },
+        { LDNS_ECC, "ECC" },
+        { LDNS_RSASHA1, "RSASHA1" },
+        { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" },
+        { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
+#ifdef USE_SHA2
+	{ LDNS_RSASHA256, "RSASHA256"},
+	{ LDNS_RSASHA512, "RSASHA512"},
+#endif
+#ifdef USE_GOST
+	{ LDNS_ECC_GOST, "ECC-GOST"},
+#endif
+#ifdef USE_ECDSA
+        { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
+        { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
+#endif
+        { LDNS_INDIRECT, "INDIRECT" },
+        { LDNS_PRIVATEDNS, "PRIVATEDNS" },
+        { LDNS_PRIVATEOID, "PRIVATEOID" },
+        { 0, NULL }
+};
+
+/* Taken from RFC 4398  */
+ldns_lookup_table ldns_cert_algorithms[] = {
+        { LDNS_CERT_PKIX, "PKIX" },
+        { LDNS_CERT_SPKI, "SPKI" },
+        { LDNS_CERT_PGP, "PGP" },
+        { LDNS_CERT_IPKIX, "IPKIX" },
+        { LDNS_CERT_ISPKI, "ISPKI" },
+        { LDNS_CERT_IPGP, "IPGP" },
+        { LDNS_CERT_ACPKIX, "ACPKIX" },
+        { LDNS_CERT_IACPKIX, "IACPKIX" },
+        { LDNS_CERT_URI, "URI" },
+        { LDNS_CERT_OID, "OID" },
+        { 0, NULL }
+};
+
+/* classes  */
+ldns_lookup_table ldns_rr_classes[] = {
+        { LDNS_RR_CLASS_IN, "IN" },
+        { LDNS_RR_CLASS_CH, "CH" },
+        { LDNS_RR_CLASS_HS, "HS" },
+        { LDNS_RR_CLASS_NONE, "NONE" },
+        { LDNS_RR_CLASS_ANY, "ANY" },
+        { 0, NULL }
+};
+
+/* if these are used elsewhere */
+ldns_lookup_table ldns_rcodes[] = {
+        { LDNS_RCODE_NOERROR, "NOERROR" },
+        { LDNS_RCODE_FORMERR, "FORMERR" },
+        { LDNS_RCODE_SERVFAIL, "SERVFAIL" },
+        { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
+        { LDNS_RCODE_NOTIMPL, "NOTIMPL" },
+        { LDNS_RCODE_REFUSED, "REFUSED" },
+        { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
+        { LDNS_RCODE_YXRRSET, "YXRRSET" },
+        { LDNS_RCODE_NXRRSET, "NXRRSET" },
+        { LDNS_RCODE_NOTAUTH, "NOTAUTH" },
+        { LDNS_RCODE_NOTZONE, "NOTZONE" },
+        { 0, NULL }
+};
+
+ldns_lookup_table ldns_opcodes[] = {
+        { LDNS_PACKET_QUERY, "QUERY" },
+        { LDNS_PACKET_IQUERY, "IQUERY" },
+        { LDNS_PACKET_STATUS, "STATUS" },
+	{ LDNS_PACKET_NOTIFY, "NOTIFY" },
+	{ LDNS_PACKET_UPDATE, "UPDATE" },
+        { 0, NULL }
+};
+
+const ldns_output_format   ldns_output_format_nocomments_record = { 0, NULL };
+const ldns_output_format  *ldns_output_format_nocomments 
+			= &ldns_output_format_nocomments_record;
+const ldns_output_format   ldns_output_format_onlykeyids_record = {
+	LDNS_COMMENT_KEY, NULL
+};
+const ldns_output_format  *ldns_output_format_onlykeyids
+			= &ldns_output_format_onlykeyids_record;
+const ldns_output_format  *ldns_output_format_default
+			= &ldns_output_format_onlykeyids_record;
+
+const ldns_output_format   ldns_output_format_bubblebabble_record = { 
+	LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
+};
+const ldns_output_format  *ldns_output_format_bubblebabble 
+			= &ldns_output_format_bubblebabble_record;
+
+static bool
+ldns_output_format_covers_type(const ldns_output_format* fmt, ldns_rr_type t)
+{
+	return fmt && (fmt->flags & LDNS_FMT_RFC3597) &&
+		((ldns_output_format_storage*)fmt)->bitmap &&
+		ldns_nsec_bitmap_covers_type(
+				((ldns_output_format_storage*)fmt)->bitmap, t);
+}
+
+ldns_status
+ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type t)
+{
+	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
+	ldns_status s;
+	
+	assert(fmt != NULL);
+	
+	if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
+		ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
+	}
+	if (! fmt_st->bitmap) {
+		s = ldns_rdf_bitmap_known_rr_types_space(&fmt_st->bitmap);
+		if (s != LDNS_STATUS_OK) {
+			return s;
+		}
+	}
+	return ldns_nsec_bitmap_set_type(fmt_st->bitmap, t);
+}
+
+ldns_status
+ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type t)
+{
+	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
+	ldns_status s;
+	
+	assert(fmt != NULL);
+
+	if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
+		ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
+	}
+	if (! fmt_st->bitmap) {
+		s = ldns_rdf_bitmap_known_rr_types(&fmt_st->bitmap);
+		if (s != LDNS_STATUS_OK) {
+			return s;
+		}
+	}
+	return ldns_nsec_bitmap_clear_type(fmt_st->bitmap, t);
+}
+
+ldns_status
+ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
+{
+	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
+	if (lt && lt->name) {
+		ldns_buffer_printf(output, "%s", lt->name);
+	} else {
+		ldns_buffer_printf(output, "OPCODE%u", opcode);
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode)
+{
+	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
+	if (lt && lt->name) {
+		ldns_buffer_printf(output, "%s", lt->name);
+	} else {
+		ldns_buffer_printf(output, "RCODE%u", rcode);
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_algorithm2buffer_str(ldns_buffer *output,
+                          ldns_algorithm algorithm)
+{
+	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms,
+	                                          algorithm);
+	if (lt && lt->name) {
+		ldns_buffer_printf(output, "%s", lt->name);
+	} else {
+		ldns_buffer_printf(output, "ALG%u", algorithm);
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_cert_algorithm2buffer_str(ldns_buffer *output,
+                               ldns_cert_algorithm cert_algorithm)
+{
+	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms,
+	                                          cert_algorithm);
+	if (lt && lt->name) {
+		ldns_buffer_printf(output, "%s", lt->name);
+	} else {
+		ldns_buffer_printf(output, "CERT_ALG%u",
+		                   cert_algorithm);
+	}
+	return ldns_buffer_status(output);
+}
+
+char *
+ldns_pkt_opcode2str(ldns_pkt_opcode opcode)
+{
+	char *str;
+	ldns_buffer *buf;
+
+	buf = ldns_buffer_new(12);
+	if (!buf) {
+		return NULL;
+	}
+
+	str = NULL;
+	if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
+		str = ldns_buffer_export2str(buf);
+	}
+
+	ldns_buffer_free(buf);
+	return str;
+}
+
+char *
+ldns_pkt_rcode2str(ldns_pkt_rcode rcode)
+{
+	char *str;
+	ldns_buffer *buf;
+
+	buf = ldns_buffer_new(10);
+	if (!buf) {
+		return NULL;
+	}
+
+	str = NULL;
+	if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
+		str = ldns_buffer_export2str(buf);
+	}
+
+	ldns_buffer_free(buf);
+	return str;
+}
+
+char *
+ldns_pkt_algorithm2str(ldns_algorithm algorithm)
+{
+	char *str;
+	ldns_buffer *buf;
+
+	buf = ldns_buffer_new(10);
+	if (!buf) {
+		return NULL;
+	}
+
+	str = NULL;
+	if (ldns_algorithm2buffer_str(buf, algorithm)
+	    == LDNS_STATUS_OK) {
+		str = ldns_buffer_export2str(buf);
+	}
+
+	ldns_buffer_free(buf);
+	return str;
+}
+
+char *
+ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
+{
+	char *str;
+	ldns_buffer *buf;
+
+	buf = ldns_buffer_new(10);
+	if (!buf) {
+		return NULL;
+	}
+
+	str = NULL;
+	if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
+	    == LDNS_STATUS_OK) {
+		str = ldns_buffer_export2str(buf);
+	}
+
+	ldns_buffer_free(buf);
+	return str;
+}
+
+
+/* do NOT pass compressed data here :p */
+ldns_status
+ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
+{
+	/* can we do with 1 pos var? or without at all? */
+	uint8_t src_pos = 0;
+	uint8_t len;
+	uint8_t *data;
+	uint8_t i;
+	unsigned char c;
+
+	data = (uint8_t*)ldns_rdf_data(dname);
+	len = data[src_pos];
+
+	if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) {
+		/* too large, return */
+		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+	}
+
+	/* special case: root label */
+	if (1 == ldns_rdf_size(dname)) {
+		ldns_buffer_printf(output, ".");
+	} else {
+		while ((len > 0) && src_pos < ldns_rdf_size(dname)) {
+			src_pos++;
+			for(i = 0; i < len; i++) {
+				/* paranoia check for various 'strange'
+				   characters in dnames
+				*/
+				c = (unsigned char) data[src_pos];
+				if(c == '.' || c == ';' ||
+				   c == '(' || c == ')' ||
+				   c == '\\') {
+					ldns_buffer_printf(output, "\\%c",
+							data[src_pos]);
+				} else if (!(isascii(c) && isgraph(c))) {
+					ldns_buffer_printf(output, "\\%03u",
+						        data[src_pos]);
+				} else {
+					ldns_buffer_printf(output, "%c", data[src_pos]);
+				}
+				src_pos++;
+			}
+
+			if (src_pos < ldns_rdf_size(dname)) {
+				ldns_buffer_printf(output, ".");
+			}
+			len = data[src_pos];
+		}
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	uint8_t data = ldns_rdf_data(rdf)[0];
+	ldns_buffer_printf(output, "%lu", (unsigned long) data);
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
+	ldns_buffer_printf(output, "%lu", (unsigned long) data);
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf));
+	ldns_buffer_printf(output, "%lu", (unsigned long) data);
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	/* create a YYYYMMDDHHMMSS string if possible */
+	struct tm tm;
+	char date_buf[16];
+
+	memset(&tm, 0, sizeof(tm));
+	if (ldns_serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
+	    && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
+		ldns_buffer_printf(output, "%s", date_buf);
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	char str[INET_ADDRSTRLEN];
+
+	if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) {
+		ldns_buffer_printf(output, "%s", str);
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	char str[INET6_ADDRSTRLEN];
+
+	if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) {
+		ldns_buffer_printf(output, "%s", str);
+	}
+
+	return ldns_buffer_status(output);
+}
+
+static void 
+ldns_characters2buffer_str(ldns_buffer* output,
+		size_t amount, const uint8_t* characters)
+{
+	uint8_t ch;
+	while (amount > 0) {
+		ch = *characters++;
+		if (isprint((int)ch) || ch == '\t') {
+			if (ch == '\"' || ch == '\\')
+				ldns_buffer_printf(output, "\\%c", ch);
+			else
+				ldns_buffer_printf(output, "%c", ch);
+		} else {
+			ldns_buffer_printf(output, "\\%03u",
+                                (unsigned)(uint8_t) ch);
+		}
+		amount--;
+	}
+}
+
+ldns_status
+ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
+{
+        if(ldns_rdf_size(rdf) < 1) {
+                return LDNS_STATUS_WIRE_RDATA_ERR;
+        }
+        if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
+                return LDNS_STATUS_WIRE_RDATA_ERR;
+        }
+	ldns_buffer_printf(output, "\"");
+	ldns_characters2buffer_str(output, 
+			ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf) + 1);
+	ldns_buffer_printf(output, "\"");
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
+	char *b64 = LDNS_XMALLOC(char, size);
+	if(!b64) return LDNS_STATUS_MEM_ERR;
+	if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
+		ldns_buffer_printf(output, "%s", b64);
+	}
+	LDNS_FREE(b64);
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	size_t size;
+	char *b32;
+	if(ldns_rdf_size(rdf) == 0)
+		return LDNS_STATUS_OK;
+        /* remove -1 for the b32-hash-len octet */
+	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
+        /* add one for the end nul for the string */
+	b32 = LDNS_XMALLOC(char, size + 1);
+	if(!b32) return LDNS_STATUS_MEM_ERR;
+	size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
+		ldns_rdf_size(rdf) - 1, b32, size+1);
+	if (size > 0) {
+		ldns_buffer_printf(output, "%s", b32);
+	}
+	LDNS_FREE(b32);
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	size_t i;
+	for (i = 0; i < ldns_rdf_size(rdf); i++) {
+		ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]);
+	}
+
+	return ldns_buffer_status(output);
+}
+
+static ldns_status
+ldns_rdf2buffer_str_type_fmt(ldns_buffer *output,
+		const ldns_output_format* fmt, const ldns_rdf *rdf)
+{
+        uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
+
+	if (! ldns_output_format_covers_type(fmt, data) &&
+			ldns_rr_descript(data) &&
+			ldns_rr_descript(data)->_name) {
+
+		ldns_buffer_printf(output, "%s",ldns_rr_descript(data)->_name);
+	} else {
+		ldns_buffer_printf(output, "TYPE%u", data);
+	}
+	return  ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	return ldns_rdf2buffer_str_type_fmt(output,
+			ldns_output_format_default, rdf);
+}
+
+ldns_status
+ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
+	ldns_lookup_table *lt;
+
+ 	lt = ldns_lookup_by_id(ldns_rr_classes, (int) data);
+	if (lt) {
+		ldns_buffer_printf(output, "\t%s", lt->name);
+	} else {
+		ldns_buffer_printf(output, "\tCLASS%d", data);
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf)
+{
+        uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
+	ldns_lookup_table *lt;
+ 	lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data);
+	if (lt) {
+		ldns_buffer_printf(output, "%s", lt->name);
+	} else {
+		ldns_buffer_printf(output, "%d", data);
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	return ldns_rdf2buffer_str_int8(output, rdf);
+}
+
+static void
+loc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent)
+{
+	uint8_t i;
+	/* is it 0.<two digits> ? */
+	if(exponent < 2) {
+		if(exponent == 1)
+			mantissa *= 10;
+		ldns_buffer_printf(output, "0.%02ld", (long)mantissa);
+		return;
+	}
+	/* always <digit><string of zeros> */
+	ldns_buffer_printf(output, "%d", (int)mantissa);
+	for(i=0; i<exponent-2; i++)
+		ldns_buffer_printf(output, "0");
+}
+
+ldns_status
+ldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type)
+{
+	const ldns_rr_descriptor *descriptor;
+
+	descriptor = ldns_rr_descript(type);
+
+	switch (type) {
+		case LDNS_RR_TYPE_IXFR:
+			ldns_buffer_printf(output, "IXFR");
+			break;
+		case LDNS_RR_TYPE_AXFR:
+			ldns_buffer_printf(output, "AXFR");
+			break;
+		case LDNS_RR_TYPE_MAILA:
+			ldns_buffer_printf(output, "MAILA");
+			break;
+		case LDNS_RR_TYPE_MAILB:
+			ldns_buffer_printf(output, "MAILB");
+			break;
+		case LDNS_RR_TYPE_ANY:
+			ldns_buffer_printf(output, "ANY");
+			break;
+		default:
+			if (descriptor && descriptor->_name) {
+				ldns_buffer_printf(output, "%s", descriptor->_name);
+			} else {
+				ldns_buffer_printf(output, "TYPE%u", type);
+			}
+	}
+	return ldns_buffer_status(output);
+}
+
+char *
+ldns_rr_type2str(const ldns_rr_type type)
+{
+	char *str;
+	ldns_buffer *buf;
+
+	buf = ldns_buffer_new(10);
+	if (!buf) {
+		return NULL;
+	}
+
+	str = NULL;
+	if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
+		str = ldns_buffer_export2str(buf);
+	}
+
+	ldns_buffer_free(buf);
+	return str;
+}
+
+
+ldns_status
+ldns_rr_class2buffer_str(ldns_buffer *output,
+                         const ldns_rr_class klass)
+{
+	ldns_lookup_table *lt;
+
+	lt = ldns_lookup_by_id(ldns_rr_classes, klass);
+	if (lt) {
+		ldns_buffer_printf(output, "%s", lt->name);
+	} else {
+		ldns_buffer_printf(output, "CLASS%d", klass);
+	}
+	return ldns_buffer_status(output);
+}
+
+char *
+ldns_rr_class2str(const ldns_rr_class klass)
+{
+	ldns_buffer *buf;
+	char *str;
+
+	buf = ldns_buffer_new(10);
+	if (!buf) {
+		return NULL;
+	}
+
+	str = NULL;
+	if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
+		str = ldns_buffer_export2str(buf);
+	}
+	ldns_buffer_free(buf);
+	return str;
+}
+
+ldns_status
+ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	/* we could do checking (ie degrees < 90 etc)? */
+	uint8_t version;
+	uint8_t size;
+	uint8_t horizontal_precision;
+	uint8_t vertical_precision;
+	uint32_t longitude;
+	uint32_t latitude;
+	uint32_t altitude;
+	char northerness;
+	char easterness;
+	uint32_t h;
+	uint32_t m;
+	double s;
+
+	uint32_t equator = (uint32_t) ldns_power(2, 31);
+
+        if(ldns_rdf_size(rdf) < 1) {
+                return LDNS_STATUS_WIRE_RDATA_ERR;
+        }
+       	version = ldns_rdf_data(rdf)[0];
+	if (version == 0) {
+		if(ldns_rdf_size(rdf) < 16) {
+			return LDNS_STATUS_WIRE_RDATA_ERR;
+		}
+		size = ldns_rdf_data(rdf)[1];
+		horizontal_precision = ldns_rdf_data(rdf)[2];
+		vertical_precision = ldns_rdf_data(rdf)[3];
+
+		latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]);
+		longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]);
+		altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]);
+
+		if (latitude > equator) {
+			northerness = 'N';
+			latitude = latitude - equator;
+		} else {
+			northerness = 'S';
+			latitude = equator - latitude;
+		}
+		h = latitude / (1000 * 60 * 60);
+		latitude = latitude % (1000 * 60 * 60);
+		m = latitude / (1000 * 60);
+		latitude = latitude % (1000 * 60);
+		s = (double) latitude / 1000.0;
+		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
+			h, m, s, northerness);
+
+		if (longitude > equator) {
+			easterness = 'E';
+			longitude = longitude - equator;
+		} else {
+			easterness = 'W';
+			longitude = equator - longitude;
+		}
+		h = longitude / (1000 * 60 * 60);
+		longitude = longitude % (1000 * 60 * 60);
+		m = longitude / (1000 * 60);
+		longitude = longitude % (1000 * 60);
+		s = (double) longitude / (1000.0);
+		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
+			h, m, s, easterness);
+
+
+		s = ((double) altitude) / 100;
+		s -= 100000;
+
+		if(altitude%100 != 0)
+			ldns_buffer_printf(output, "%.2f", s);
+		else
+			ldns_buffer_printf(output, "%.0f", s);
+
+		ldns_buffer_printf(output, "m ");
+
+		loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
+		ldns_buffer_printf(output, "m ");
+
+		loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
+			horizontal_precision & 0x0f);
+		ldns_buffer_printf(output, "m ");
+
+		loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
+			vertical_precision & 0x0f);
+		ldns_buffer_printf(output, "m");
+
+		return ldns_buffer_status(output);
+	} else {
+		return ldns_rdf2buffer_str_hex(output, rdf);
+	}
+}
+
+ldns_status
+ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf));
+	return ldns_rdf2buffer_str_hex(output, rdf);
+}
+
+ldns_status
+ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	ldns_buffer_printf(output, "0x");
+	return ldns_rdf2buffer_str_hex(output, rdf);
+}
+
+ldns_status
+ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	return ldns_rdf2buffer_str_hex(output, rdf);
+}
+
+ldns_status
+ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	/* protocol, followed by bitmap of services */
+	struct protoent *protocol;
+	char *proto_name = NULL;
+	uint8_t protocol_nr;
+	struct servent *service;
+	uint16_t current_service;
+
+        if(ldns_rdf_size(rdf) < 1) {
+                return LDNS_STATUS_WIRE_RDATA_ERR;
+        }
+	protocol_nr = ldns_rdf_data(rdf)[0];
+	protocol = getprotobynumber((int) protocol_nr);
+	if (protocol && (protocol->p_name != NULL)) {
+		proto_name = protocol->p_name;
+		ldns_buffer_printf(output, "%s ", protocol->p_name);
+	} else {
+		ldns_buffer_printf(output, "%u ", protocol_nr);
+	}
+
+#ifdef HAVE_ENDPROTOENT
+	endprotoent();
+#endif
+
+	for (current_service = 0;
+	     current_service < (ldns_rdf_size(rdf)-1)*8; current_service++) {
+		if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) {
+			service = getservbyport((int) htons(current_service),
+			                        proto_name);
+			if (service && service->s_name) {
+				ldns_buffer_printf(output, "%s ", service->s_name);
+			} else {
+				ldns_buffer_printf(output, "%u ", current_service);
+			}
+#ifdef HAVE_ENDSERVENT
+			endservent();
+#endif
+		}
+	}
+	return ldns_buffer_status(output);
+}
+
+static ldns_status
+ldns_rdf2buffer_str_nsec_fmt(ldns_buffer *output,
+		const ldns_output_format* fmt, const ldns_rdf *rdf)
+{
+	/* Note: this code is duplicated in higher.c in
+	 * ldns_nsec_type_check() function
+	 */
+	uint8_t window_block_nr;
+	uint8_t bitmap_length;
+	uint16_t type;
+	uint16_t pos = 0;
+	uint16_t bit_pos;
+	uint8_t *data = ldns_rdf_data(rdf);
+
+	while((size_t)(pos + 2) < ldns_rdf_size(rdf)) {
+		window_block_nr = data[pos];
+		bitmap_length = data[pos + 1];
+		pos += 2;
+		if (ldns_rdf_size(rdf) < pos + bitmap_length) {
+			return LDNS_STATUS_WIRE_RDATA_ERR;
+		}
+		for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
+			if (! ldns_get_bit(&data[pos], bit_pos)) {
+				continue;
+			}
+			type = 256 * (uint16_t) window_block_nr + bit_pos;
+
+			if (! ldns_output_format_covers_type(fmt, type) &&
+					ldns_rr_descript(type) &&
+					ldns_rr_descript(type)->_name){
+
+				ldns_buffer_printf(output, "%s ",
+						ldns_rr_descript(type)->_name);
+			} else {
+				ldns_buffer_printf(output, "TYPE%u ", type);
+			}
+		}
+		pos += (uint16_t) bitmap_length;
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	return ldns_rdf2buffer_str_nsec_fmt(output,
+			ldns_output_format_default, rdf);
+}
+
+ldns_status
+ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	uint8_t salt_length;
+	uint8_t salt_pos;
+
+	uint8_t *data = ldns_rdf_data(rdf);
+
+        if(ldns_rdf_size(rdf) < 1) {
+                return LDNS_STATUS_WIRE_RDATA_ERR;
+        }
+	salt_length = data[0];
+	/* from now there are variable length entries so remember pos */
+	if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
+		ldns_buffer_printf(output, "- ");
+	} else {
+		for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
+			ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
+		}
+		ldns_buffer_printf(output, " ");
+	}
+
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	/* period is the number of seconds */
+	if (ldns_rdf_size(rdf) != 4) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	ldns_buffer_printf(output, "%u", ldns_read_uint32(ldns_rdf_data(rdf)));
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const  ldns_rdf *rdf)
+{
+	/* tsigtime is 48 bits network order unsigned integer */
+	uint64_t tsigtime = 0;
+	uint8_t *data = ldns_rdf_data(rdf);
+	uint64_t d0, d1, d2, d3, d4, d5;
+
+	if (ldns_rdf_size(rdf) < 6) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	d0 = data[0]; /* cast to uint64 for shift operations */
+	d1 = data[1];
+	d2 = data[2];
+	d3 = data[3];
+	d4 = data[4];
+	d5 = data[5];
+	tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
+
+	ldns_buffer_printf(output, "%llu ", (long long)tsigtime);
+
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	uint8_t *data = ldns_rdf_data(rdf);
+	uint16_t address_family;
+	uint8_t prefix;
+	bool negation;
+	uint8_t adf_length;
+	size_t i;
+	size_t pos = 0;
+
+	while (pos < (unsigned int) ldns_rdf_size(rdf)) {
+                if(pos + 3 >= (unsigned)ldns_rdf_size(rdf))
+                        return LDNS_STATUS_WIRE_RDATA_ERR;
+		address_family = ldns_read_uint16(&data[pos]);
+		prefix = data[pos + 2];
+		negation = data[pos + 3] & LDNS_APL_NEGATION;
+		adf_length = data[pos + 3] & LDNS_APL_MASK;
+		if (address_family == LDNS_APL_IP4) {
+			/* check if prefix < 32? */
+			if (negation) {
+				ldns_buffer_printf(output, "!");
+			}
+			ldns_buffer_printf(output, "%u:", address_family);
+			/* address is variable length 0 - 4 */
+			for (i = 0; i < 4; i++) {
+				if (i > 0) {
+					ldns_buffer_printf(output, ".");
+				}
+				if (i < (unsigned short) adf_length) {
+                                        if(pos+i+4 >= ldns_rdf_size(rdf))
+					    return LDNS_STATUS_WIRE_RDATA_ERR;
+					ldns_buffer_printf(output, "%d",
+					                   data[pos + i + 4]);
+				} else {
+					ldns_buffer_printf(output, "0");
+				}
+			}
+			ldns_buffer_printf(output, "/%u ", prefix);
+		} else if (address_family == LDNS_APL_IP6) {
+			/* check if prefix < 128? */
+			if (negation) {
+				ldns_buffer_printf(output, "!");
+			}
+			ldns_buffer_printf(output, "%u:", address_family);
+			/* address is variable length 0 - 16 */
+			for (i = 0; i < 16; i++) {
+				if (i % 2 == 0 && i > 0) {
+					ldns_buffer_printf(output, ":");
+				}
+				if (i < (unsigned short) adf_length) {
+                                        if(pos+i+4 >= ldns_rdf_size(rdf))
+					    return LDNS_STATUS_WIRE_RDATA_ERR;
+					ldns_buffer_printf(output, "%02x",
+					                   data[pos + i + 4]);
+				} else {
+					ldns_buffer_printf(output, "00");
+				}
+			}
+			ldns_buffer_printf(output, "/%u ", prefix);
+
+		} else {
+			/* unknown address family */
+			ldns_buffer_printf(output,
+					"Unknown address family: %u data: ",
+					address_family);
+			for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
+                                if(pos+i >= ldns_rdf_size(rdf))
+                                        return LDNS_STATUS_WIRE_RDATA_ERR;
+				ldns_buffer_printf(output, "%02x", data[i]);
+			}
+		}
+		pos += 4 + adf_length;
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	size_t size;
+	char *b64;
+	if (ldns_rdf_size(rdf) < 2) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	/* Subtract the size (2) of the number that specifies the length */
+	size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
+	ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
+	if (ldns_rdf_size(rdf) > 2) {
+		b64 = LDNS_XMALLOC(char, size);
+		if(!b64)
+			return LDNS_STATUS_MEM_ERR;
+
+		if (ldns_rdf_size(rdf) > 2 &&
+		ldns_b64_ntop(ldns_rdf_data(rdf) + 2,
+					ldns_rdf_size(rdf) - 2,
+					b64, size)) {
+			ldns_buffer_printf(output, "%s", b64);
+		}
+		LDNS_FREE(b64);
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	/* wire format from
+	   http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt
+	*/
+	uint8_t *data = ldns_rdf_data(rdf);
+	uint8_t precedence;
+	uint8_t gateway_type;
+	uint8_t algorithm;
+
+	ldns_rdf *gateway = NULL;
+	uint8_t *gateway_data;
+
+	size_t public_key_size;
+	uint8_t *public_key_data;
+	ldns_rdf *public_key;
+
+	size_t offset = 0;
+	ldns_status status;
+
+	if (ldns_rdf_size(rdf) < 3) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	precedence = data[0];
+	gateway_type = data[1];
+	algorithm = data[2];
+	offset = 3;
+
+	switch (gateway_type) {
+		case 0:
+			/* no gateway */
+			break;
+		case 1:
+			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
+                        if(!gateway_data)
+                                return LDNS_STATUS_MEM_ERR;
+			if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
+				return LDNS_STATUS_ERR;
+			}
+			memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
+			gateway = ldns_rdf_new(LDNS_RDF_TYPE_A,
+					LDNS_IP4ADDRLEN , gateway_data);
+			offset += LDNS_IP4ADDRLEN;
+                        if(!gateway) {
+                                LDNS_FREE(gateway_data);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
+			break;
+		case 2:
+			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
+                        if(!gateway_data)
+                                return LDNS_STATUS_MEM_ERR;
+			if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
+				return LDNS_STATUS_ERR;
+			}
+			memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
+			offset += LDNS_IP6ADDRLEN;
+			gateway =
+				ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
+						LDNS_IP6ADDRLEN, gateway_data);
+                        if(!gateway) {
+                                LDNS_FREE(gateway_data);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
+			break;
+		case 3:
+			status = ldns_wire2dname(&gateway, data,
+					ldns_rdf_size(rdf), &offset);
+                        if(status != LDNS_STATUS_OK)
+                                return status;
+			break;
+		default:
+			/* error? */
+			break;
+	}
+
+	if (ldns_rdf_size(rdf) <= offset) {
+		return LDNS_STATUS_ERR;
+	}
+	public_key_size = ldns_rdf_size(rdf) - offset;
+	public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
+        if(!public_key_data) {
+                ldns_rdf_free(gateway);
+                return LDNS_STATUS_MEM_ERR;
+        }
+	memcpy(public_key_data, &data[offset], public_key_size);
+	public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64,
+			public_key_size, public_key_data);
+        if(!public_key) {
+                LDNS_FREE(public_key_data);
+                ldns_rdf_free(gateway);
+                return LDNS_STATUS_MEM_ERR;
+        }
+
+	ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
+	if (gateway)
+	  	(void) ldns_rdf2buffer_str(output, gateway);
+	else
+		ldns_buffer_printf(output, ".");
+	ldns_buffer_printf(output, " ");
+	(void) ldns_rdf2buffer_str(output, public_key);
+
+	ldns_rdf_free(gateway);
+	ldns_rdf_free(public_key);
+
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_ilnp64(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	if (ldns_rdf_size(rdf) != 8) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	ldns_buffer_printf(output,"%.4x:%.4x:%.4x:%.4x",
+				ldns_read_uint16(ldns_rdf_data(rdf)),
+				ldns_read_uint16(ldns_rdf_data(rdf)+2),
+				ldns_read_uint16(ldns_rdf_data(rdf)+4),
+				ldns_read_uint16(ldns_rdf_data(rdf)+6));
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_eui48(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	if (ldns_rdf_size(rdf) != 6) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
+				ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
+				ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
+				ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5]);
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	if (ldns_rdf_size(rdf) != 8) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
+				ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
+				ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
+				ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5],
+				ldns_rdf_data(rdf)[6], ldns_rdf_data(rdf)[7]);
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_tag(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	size_t nchars;
+	const uint8_t* chars;
+	char ch;
+	if (ldns_rdf_size(rdf) < 2) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	nchars = ldns_rdf_data(rdf)[0];
+	if (nchars >= ldns_rdf_size(rdf) || /* should be rdf_size - 1 */
+			nchars < 1) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	chars = ldns_rdf_data(rdf) + 1;
+	while (nchars > 0) {
+		ch = (char)*chars++;
+		if (! isalnum(ch)) {
+			return LDNS_STATUS_WIRE_RDATA_ERR;
+		}
+		ldns_buffer_printf(output, "%c", ch);
+		nchars--;
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
+{
+
+	ldns_buffer_printf(output, "\"");
+	ldns_characters2buffer_str(output,
+			ldns_rdf_size(rdf), ldns_rdf_data(rdf));
+	ldns_buffer_printf(output, "\"");
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
+{
+	uint8_t *data = ldns_rdf_data(rdf);
+	size_t rdf_size = ldns_rdf_size(rdf);
+	uint8_t hit_size;
+	uint16_t pk_size;
+	int written;
+	
+	if (rdf_size < 6) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	if ((hit_size = data[0]) == 0 ||
+			(pk_size = ldns_read_uint16(data + 2)) == 0 ||
+			rdf_size < (size_t) hit_size + pk_size + 4) {
+
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+
+	ldns_buffer_printf(output, "%d ", (int) data[1]);
+
+	for (data += 4; hit_size > 0; hit_size--, data++) {
+
+		ldns_buffer_printf(output, "%02x", (int) *data);
+	}
+	ldns_buffer_write_u8(output, (uint8_t) ' ');
+
+	if (ldns_buffer_reserve(output,
+				ldns_b64_ntop_calculate_size(pk_size))) {
+
+		written = ldns_b64_ntop(data, pk_size,
+				(char *) ldns_buffer_current(output),
+				ldns_buffer_remaining(output));
+
+		if (written > 0 &&
+				written < (int) ldns_buffer_remaining(output)) {
+
+			output->_position += written;
+		}
+	}
+	return ldns_buffer_status(output);
+}
+
+static ldns_status
+ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
+		const ldns_output_format* fmt, const ldns_rdf *rdf)
+{
+	ldns_status res = LDNS_STATUS_OK;
+
+	/*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
+	if (rdf) {
+		switch(ldns_rdf_get_type(rdf)) {
+		case LDNS_RDF_TYPE_NONE:
+			break;
+		case LDNS_RDF_TYPE_DNAME:
+			res = ldns_rdf2buffer_str_dname(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_INT8: /* Don't output mnemonics for these */
+		case LDNS_RDF_TYPE_ALG:
+		case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
+		case LDNS_RDF_TYPE_SELECTOR:
+		case LDNS_RDF_TYPE_MATCHING_TYPE:
+			res = ldns_rdf2buffer_str_int8(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_INT16:
+			res = ldns_rdf2buffer_str_int16(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_INT32:
+			res = ldns_rdf2buffer_str_int32(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_PERIOD:
+			res = ldns_rdf2buffer_str_period(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_TSIGTIME:
+			res = ldns_rdf2buffer_str_tsigtime(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_A:
+			res = ldns_rdf2buffer_str_a(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_AAAA:
+			res = ldns_rdf2buffer_str_aaaa(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_STR:
+			res = ldns_rdf2buffer_str_str(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_APL:
+			res = ldns_rdf2buffer_str_apl(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_B32_EXT:
+			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_B64:
+			res = ldns_rdf2buffer_str_b64(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_HEX:
+			res = ldns_rdf2buffer_str_hex(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_NSEC:
+			res = ldns_rdf2buffer_str_nsec_fmt(buffer, fmt, rdf);
+			break;
+		case LDNS_RDF_TYPE_NSEC3_SALT:
+			res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_TYPE:
+			res = ldns_rdf2buffer_str_type_fmt(buffer, fmt, rdf);
+			break;
+		case LDNS_RDF_TYPE_CLASS:
+			res = ldns_rdf2buffer_str_class(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_CERT_ALG:
+			res = ldns_rdf2buffer_str_cert_alg(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_UNKNOWN:
+			res = ldns_rdf2buffer_str_unknown(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_TIME:
+			res = ldns_rdf2buffer_str_time(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_HIP:
+			res = ldns_rdf2buffer_str_hip(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_LOC:
+			res = ldns_rdf2buffer_str_loc(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_WKS:
+		case LDNS_RDF_TYPE_SERVICE:
+			res = ldns_rdf2buffer_str_wks(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_NSAP:
+			res = ldns_rdf2buffer_str_nsap(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_ATMA:
+			res = ldns_rdf2buffer_str_atma(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_IPSECKEY:
+			res = ldns_rdf2buffer_str_ipseckey(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_INT16_DATA:
+			res = ldns_rdf2buffer_str_int16_data(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
+			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_ILNP64:
+			res = ldns_rdf2buffer_str_ilnp64(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_EUI48:
+			res = ldns_rdf2buffer_str_eui48(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_EUI64:
+			res = ldns_rdf2buffer_str_eui64(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_TAG:
+			res = ldns_rdf2buffer_str_tag(buffer, rdf);
+			break;
+		case LDNS_RDF_TYPE_LONG_STR:
+			res = ldns_rdf2buffer_str_long_str(buffer, rdf);
+			break;
+		}
+	} else {
+		/** This will write mangled RRs */
+		ldns_buffer_printf(buffer, "(null) ");
+		res = LDNS_STATUS_ERR;
+	}
+	return res;
+}
+
+ldns_status
+ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
+{
+	return ldns_rdf2buffer_str_fmt(buffer,ldns_output_format_default,rdf);
+}
+
+static ldns_rdf *
+ldns_b32_ext2dname(const ldns_rdf *rdf)
+{
+	size_t size;
+	char *b32;
+	ldns_rdf *out;
+	if(ldns_rdf_size(rdf) == 0)
+		return NULL;
+        /* remove -1 for the b32-hash-len octet */
+	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
+        /* add one for the end nul for the string */
+	b32 = LDNS_XMALLOC(char, size + 2);
+	if (b32) {
+		if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1, 
+				ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
+			b32[size] = '.';
+			b32[size+1] = '\0';
+			if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
+				LDNS_FREE(b32);
+				return out;
+			}
+		}
+		LDNS_FREE(b32);
+	}
+	return NULL;
+}
+
+static ldns_status
+ldns_rr2buffer_str_rfc3597(ldns_buffer *output, const ldns_rr *rr)
+{
+	size_t total_rdfsize = 0;
+	size_t i, j;
+
+	ldns_buffer_printf(output, "TYPE%u\t", ldns_rr_get_type(rr));
+	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+		total_rdfsize += ldns_rdf_size(ldns_rr_rdf(rr, i));
+	}
+	if (total_rdfsize == 0) {
+		ldns_buffer_printf(output, "\\# 0\n");
+		return ldns_buffer_status(output);
+	}
+	ldns_buffer_printf(output, "\\# %d ", total_rdfsize);
+	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+		for (j = 0; j < ldns_rdf_size(ldns_rr_rdf(rr, i)); j++) {
+			ldns_buffer_printf(output, "%.2x",
+					ldns_rdf_data(ldns_rr_rdf(rr, i))[j]);
+		}
+	}
+	ldns_buffer_printf(output, "\n");
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rr2buffer_str_fmt(ldns_buffer *output, 
+		const ldns_output_format *fmt, const ldns_rr *rr)
+{
+	uint16_t i, flags;
+	ldns_status status = LDNS_STATUS_OK;
+	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
+
+	if (fmt_st == NULL) {
+		fmt_st = (ldns_output_format_storage*)
+			  ldns_output_format_default;
+	}
+	if (!rr) {
+		if (LDNS_COMMENT_NULLS & fmt_st->flags) {
+			ldns_buffer_printf(output, "; (null)\n");
+		}
+		return ldns_buffer_status(output);
+	}
+	if (ldns_rr_owner(rr)) {
+		status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
+	}
+	if (status != LDNS_STATUS_OK) {
+		return status;
+	}
+
+	/* TTL should NOT be printed if it is a question */
+	if (!ldns_rr_is_question(rr)) {
+		ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
+	}
+
+	ldns_buffer_printf(output, "\t");
+	status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
+	if (status != LDNS_STATUS_OK) {
+		return status;
+	}
+	ldns_buffer_printf(output, "\t");
+
+	if (ldns_output_format_covers_type(fmt, ldns_rr_get_type(rr))) {
+		return ldns_rr2buffer_str_rfc3597(output, rr);
+	}
+	status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
+	if (status != LDNS_STATUS_OK) {
+		return status;
+	}
+
+	if (ldns_rr_rd_count(rr) > 0) {
+		ldns_buffer_printf(output, "\t");
+	} else if (!ldns_rr_is_question(rr)) {
+		ldns_buffer_printf(output, "\t\\# 0");
+	}
+
+	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+		/* ldns_rdf2buffer_str handles NULL input fine! */
+		if ((fmt_st->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
+				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
+				((/* inception  */ i == 4 &&
+				  ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) == 
+							LDNS_RDF_TYPE_TIME) ||
+				  (/* expiration */ i == 5 &&
+				   ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
+				   			LDNS_RDF_TYPE_TIME) ||
+				  (/* signature  */ i == 8 &&
+				   ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
+				   			LDNS_RDF_TYPE_B64))) {
+
+			ldns_buffer_printf(output, "(null)");
+			status = ldns_buffer_status(output);
+		} else if ((fmt_st->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
+				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
+				/* serial */ i == 2 &&
+			 	ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
+			 				LDNS_RDF_TYPE_INT32) {
+			ldns_buffer_printf(output, "%10lu",
+				(unsigned long) ldns_read_uint32(
+					ldns_rdf_data(ldns_rr_rdf(rr, 2))));
+			status = ldns_buffer_status(output);
+		} else {
+			status = ldns_rdf2buffer_str_fmt(output,
+					fmt, ldns_rr_rdf(rr, i));
+		}
+		if(status != LDNS_STATUS_OK)
+			return status;
+		if (i < ldns_rr_rd_count(rr) - 1) {
+			ldns_buffer_printf(output, " ");
+		}
+	}
+	/* per RR special comments - handy for DNSSEC types */
+	/* check to prevent question sec. rr from
+	 * getting here */
+	if (ldns_rr_rd_count(rr) > 0) {
+		switch (ldns_rr_get_type(rr)) {
+		case LDNS_RR_TYPE_DNSKEY:
+			/* if ldns_rr_rd_count(rr) > 0
+				then ldns_rr_rdf(rr, 0) exists! */
+			if (! (fmt_st->flags & LDNS_COMMENT_KEY)) {
+				break;
+			}
+			flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
+			ldns_buffer_printf(output, " ;{");
+			if (fmt_st->flags & LDNS_COMMENT_KEY_ID) {
+				ldns_buffer_printf(output, "id = %u",
+					(unsigned int) ldns_calc_keytag(rr));
+			}
+			if ((fmt_st->flags & LDNS_COMMENT_KEY_TYPE) &&
+					(flags & LDNS_KEY_ZONE_KEY)){
+
+				if (flags & LDNS_KEY_SEP_KEY) {
+					ldns_buffer_printf(output, " (ksk)");
+				} else {
+					ldns_buffer_printf(output, " (zsk)");
+				}
+				if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE){
+					ldns_buffer_printf(output, ", ");
+				}
+			} else if (fmt_st->flags
+					& (LDNS_COMMENT_KEY_ID
+						|LDNS_COMMENT_KEY_SIZE)) {
+				ldns_buffer_printf( output, ", ");
+			}
+			if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE) {
+				ldns_buffer_printf(output, "size = %db",
+					ldns_rr_dnskey_key_size(rr));
+			}
+			ldns_buffer_printf(output, "}");
+			break;
+		case LDNS_RR_TYPE_RRSIG:
+			if ((fmt_st->flags & LDNS_COMMENT_KEY)
+					&& (fmt_st->flags& LDNS_COMMENT_RRSIGS)
+					&& ldns_rr_rdf(rr, 6) != NULL) {
+				ldns_buffer_printf(output, " ;{id = %d}",
+						ldns_rdf2native_int16(
+							ldns_rr_rdf(rr, 6)));
+			}
+			break;
+		case LDNS_RR_TYPE_DS:
+			if ((fmt_st->flags & LDNS_COMMENT_BUBBLEBABBLE) &&
+					ldns_rr_rdf(rr, 3) != NULL) {
+
+				uint8_t *data = ldns_rdf_data(
+						ldns_rr_rdf(rr, 3));
+				size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
+				char *babble = ldns_bubblebabble(data, len);
+				if(babble) {
+					ldns_buffer_printf(output,
+							" ;{%s}", babble);
+				}
+				LDNS_FREE(babble);
+			}
+			break;
+		case LDNS_RR_TYPE_NSEC3:
+			if (! (fmt_st->flags & LDNS_COMMENT_FLAGS) &&
+				! (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
+				break;
+			}
+			ldns_buffer_printf(output, " ;{");
+			if ((fmt_st->flags & LDNS_COMMENT_FLAGS)) {
+				if (ldns_nsec3_optout(rr)) {
+					ldns_buffer_printf(output,
+						" flags: optout");
+				} else {
+					ldns_buffer_printf(output," flags: -");
+				}
+				if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
+						fmt_st->hashmap != NULL) {
+					ldns_buffer_printf(output, ", ");
+				}
+			}
+			if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
+					fmt_st->hashmap != NULL) {
+				ldns_rbnode_t *node;
+				ldns_rdf *key = ldns_dname_label(
+						ldns_rr_owner(rr), 0);
+				if (key) {
+					node = ldns_rbtree_search(
+						fmt_st->hashmap,
+						(void *) key);
+					if (node->data) {
+						ldns_buffer_printf(output,
+							"from: ");
+						(void) ldns_rdf2buffer_str(
+							output,
+							ldns_dnssec_name_name(
+							   (ldns_dnssec_name*)
+							   node->data
+							));
+					}
+					ldns_rdf_free(key);
+				}
+				key = ldns_b32_ext2dname(
+						ldns_nsec3_next_owner(rr));
+				if (key) {
+					node = ldns_rbtree_search(
+						fmt_st->hashmap,
+						(void *) key);
+					if (node->data) {
+						ldns_buffer_printf(output,
+							" to: ");
+						(void) ldns_rdf2buffer_str(
+							output,
+							ldns_dnssec_name_name(
+							   (ldns_dnssec_name*)
+							   node->data
+							));
+					}
+					ldns_rdf_free(key);
+				}
+			}
+			ldns_buffer_printf(output, "}");
+			break;
+		default:
+			break;
+
+		}
+	}
+	/* last */
+	ldns_buffer_printf(output, "\n");
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
+{
+	return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
+}
+
+ldns_status
+ldns_rr_list2buffer_str_fmt(ldns_buffer *output, 
+		const ldns_output_format *fmt, const ldns_rr_list *list)
+{
+	uint16_t i;
+
+	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
+		(void) ldns_rr2buffer_str_fmt(output, fmt, 
+				ldns_rr_list_rr(list, i));
+	}
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
+{
+	return ldns_rr_list2buffer_str_fmt(
+			output, ldns_output_format_default, list);
+}
+
+ldns_status
+ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
+{
+	ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes,
+			                    (int) ldns_pkt_get_opcode(pkt));
+	ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes,
+			                    (int) ldns_pkt_get_rcode(pkt));
+
+	ldns_buffer_printf(output, ";; ->>HEADER<<- ");
+	if (opcode) {
+		ldns_buffer_printf(output, "opcode: %s, ", opcode->name);
+	} else {
+		ldns_buffer_printf(output, "opcode: ?? (%u), ",
+				ldns_pkt_get_opcode(pkt));
+	}
+	if (rcode) {
+		ldns_buffer_printf(output, "rcode: %s, ", rcode->name);
+	} else {
+		ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt));
+	}
+	ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt));
+	ldns_buffer_printf(output, ";; flags: ");
+
+	if (ldns_pkt_qr(pkt)) {
+		ldns_buffer_printf(output, "qr ");
+	}
+	if (ldns_pkt_aa(pkt)) {
+		ldns_buffer_printf(output, "aa ");
+	}
+	if (ldns_pkt_tc(pkt)) {
+		ldns_buffer_printf(output, "tc ");
+	}
+	if (ldns_pkt_rd(pkt)) {
+		ldns_buffer_printf(output, "rd ");
+	}
+	if (ldns_pkt_cd(pkt)) {
+		ldns_buffer_printf(output, "cd ");
+	}
+	if (ldns_pkt_ra(pkt)) {
+		ldns_buffer_printf(output, "ra ");
+	}
+	if (ldns_pkt_ad(pkt)) {
+		ldns_buffer_printf(output, "ad ");
+	}
+	ldns_buffer_printf(output, "; ");
+	ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt));
+	ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt));
+	ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt));
+	ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt));
+	return ldns_buffer_status(output);
+}
+
+ldns_status
+ldns_pkt2buffer_str_fmt(ldns_buffer *output, 
+		const ldns_output_format *fmt, const ldns_pkt *pkt)
+{
+	uint16_t i;
+	ldns_status status = LDNS_STATUS_OK;
+	char *tmp;
+	struct timeval time;
+	time_t time_tt;
+
+	if (!pkt) {
+		ldns_buffer_printf(output, "null");
+		return LDNS_STATUS_OK;
+	}
+
+	if (ldns_buffer_status_ok(output)) {
+		status = ldns_pktheader2buffer_str(output, pkt);
+		if (status != LDNS_STATUS_OK) {
+			return status;
+		}
+
+		ldns_buffer_printf(output, "\n");
+
+		ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; ");
+
+
+		for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
+			status = ldns_rr2buffer_str_fmt(output, fmt,
+				       ldns_rr_list_rr(
+					       ldns_pkt_question(pkt), i));
+			if (status != LDNS_STATUS_OK) {
+				return status;
+			}
+		}
+		ldns_buffer_printf(output, "\n");
+
+		ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
+		for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
+			status = ldns_rr2buffer_str_fmt(output, fmt,
+				       ldns_rr_list_rr(
+					       ldns_pkt_answer(pkt), i));
+			if (status != LDNS_STATUS_OK) {
+				return status;
+			}
+
+		}
+		ldns_buffer_printf(output, "\n");
+
+		ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
+
+		for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
+			status = ldns_rr2buffer_str_fmt(output, fmt,
+				       ldns_rr_list_rr(
+					       ldns_pkt_authority(pkt), i));
+			if (status != LDNS_STATUS_OK) {
+				return status;
+			}
+		}
+		ldns_buffer_printf(output, "\n");
+
+		ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
+		for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
+			status = ldns_rr2buffer_str_fmt(output, fmt,
+				       ldns_rr_list_rr(
+					       ldns_pkt_additional(pkt), i));
+			if (status != LDNS_STATUS_OK) {
+				return status;
+			}
+
+		}
+		ldns_buffer_printf(output, "\n");
+		/* add some futher fields */
+		ldns_buffer_printf(output, ";; Query time: %d msec\n",
+				ldns_pkt_querytime(pkt));
+		if (ldns_pkt_edns(pkt)) {
+			ldns_buffer_printf(output,
+				   ";; EDNS: version %u; flags:",
+				   ldns_pkt_edns_version(pkt));
+			if (ldns_pkt_edns_do(pkt)) {
+				ldns_buffer_printf(output, " do");
+			}
+			/* the extended rcode is the value set, shifted four bits,
+			 * and or'd with the original rcode */
+			if (ldns_pkt_edns_extended_rcode(pkt)) {
+				ldns_buffer_printf(output, " ; ext-rcode: %d",
+					(ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt)));
+			}
+			ldns_buffer_printf(output, " ; udp: %u\n",
+					   ldns_pkt_edns_udp_size(pkt));
+
+			if (ldns_pkt_edns_data(pkt)) {
+				ldns_buffer_printf(output, ";; Data: ");
+				(void)ldns_rdf2buffer_str(output,
+							  ldns_pkt_edns_data(pkt));
+				ldns_buffer_printf(output, "\n");
+			}
+		}
+		if (ldns_pkt_tsig(pkt)) {
+			ldns_buffer_printf(output, ";; TSIG:\n;; ");
+			(void) ldns_rr2buffer_str_fmt(
+					output, fmt, ldns_pkt_tsig(pkt));
+			ldns_buffer_printf(output, "\n");
+		}
+		if (ldns_pkt_answerfrom(pkt)) {
+			tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
+			ldns_buffer_printf(output, ";; SERVER: %s\n", tmp);
+			LDNS_FREE(tmp);
+		}
+		time = ldns_pkt_timestamp(pkt);
+		time_tt = (time_t)time.tv_sec;
+		ldns_buffer_printf(output, ";; WHEN: %s",
+				(char*)ctime(&time_tt));
+
+		ldns_buffer_printf(output, ";; MSG SIZE  rcvd: %d\n",
+				(int)ldns_pkt_size(pkt));
+	} else {
+		return ldns_buffer_status(output);
+	}
+	return status;
+}
+
+ldns_status
+ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
+{
+	return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
+}
+
+
+#ifdef HAVE_SSL
+static ldns_status
+ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
+{
+	ldns_status status;
+	size_t i;
+	ldns_rdf *b64_bignum;
+
+	ldns_buffer_printf(output, "Key: ");
+
+ 	i = ldns_key_hmac_size(k);
+	b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k));
+	status = ldns_rdf2buffer_str(output, b64_bignum);
+	ldns_rdf_deep_free(b64_bignum);
+	ldns_buffer_printf(output, "\n");
+	return status;
+}
+#endif
+
+#if defined(HAVE_SSL) && defined(USE_GOST)
+static ldns_status
+ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
+{
+	unsigned char* pp = NULL;
+	int ret;
+	ldns_rdf *b64_bignum;
+	ldns_status status;
+
+	ldns_buffer_printf(output, "GostAsn1: ");
+
+	ret = i2d_PrivateKey(p, &pp);
+	b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp);
+	status = ldns_rdf2buffer_str(output, b64_bignum);
+
+	ldns_rdf_deep_free(b64_bignum);
+	OPENSSL_free(pp);
+	ldns_buffer_printf(output, "\n");
+	return status;
+}
+#endif
+
+ldns_status
+ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
+{
+	ldns_status status = LDNS_STATUS_OK;
+	unsigned char  *bignum;
+#ifdef HAVE_SSL
+#  ifndef S_SPLINT_S
+	uint16_t i;
+#  endif
+	/* not used when ssl is not defined */
+	/*@unused@*/
+	ldns_rdf *b64_bignum = NULL;
+
+	RSA *rsa;
+	DSA *dsa;
+#endif /* HAVE_SSL */
+
+	if (!k) {
+		return LDNS_STATUS_ERR;
+	}
+
+	bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
+	if (!bignum) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (ldns_buffer_status_ok(output)) {
+#ifdef HAVE_SSL
+		switch(ldns_key_algorithm(k)) {
+			case LDNS_SIGN_RSASHA1:
+			case LDNS_SIGN_RSASHA1_NSEC3:
+			case LDNS_SIGN_RSASHA256:
+			case LDNS_SIGN_RSASHA512:
+			case LDNS_SIGN_RSAMD5:
+				/* copied by looking at dnssec-keygen output */
+				/* header */
+				rsa = ldns_key_rsa_key(k);
+
+				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
+				switch(ldns_key_algorithm(k)) {
+				case LDNS_SIGN_RSAMD5:
+					ldns_buffer_printf(output,
+								    "Algorithm: %u (RSA)\n",
+								    LDNS_RSAMD5);
+					break;
+				case LDNS_SIGN_RSASHA1:
+					ldns_buffer_printf(output,
+								    "Algorithm: %u (RSASHA1)\n",
+								    LDNS_RSASHA1);
+					break;
+				case LDNS_SIGN_RSASHA1_NSEC3:
+					ldns_buffer_printf(output,
+								    "Algorithm: %u (RSASHA1_NSEC3)\n",
+								    LDNS_RSASHA1_NSEC3);
+					break;
+#ifdef USE_SHA2
+				case LDNS_SIGN_RSASHA256:
+					ldns_buffer_printf(output,
+								    "Algorithm: %u (RSASHA256)\n",
+								    LDNS_RSASHA256);
+					break;
+				case LDNS_SIGN_RSASHA512:
+					ldns_buffer_printf(output,
+								    "Algorithm: %u (RSASHA512)\n",
+								    LDNS_RSASHA512);
+					break;
+#endif
+				default:
+#ifdef STDERR_MSGS
+					fprintf(stderr, "Warning: unknown signature ");
+					fprintf(stderr,
+						   "algorithm type %u\n",
+						   ldns_key_algorithm(k));
+#endif
+					ldns_buffer_printf(output,
+								    "Algorithm: %u (Unknown)\n",
+								    ldns_key_algorithm(k));
+					break;
+				}
+
+				/* print to buf, convert to bin, convert to b64,
+				 * print to buf */
+				ldns_buffer_printf(output, "Modulus: ");
+#ifndef S_SPLINT_S
+				i = (uint16_t)BN_bn2bin(rsa->n, bignum);
+				if (i > LDNS_MAX_KEYLEN) {
+					goto error;
+				}
+				b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+				if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+					ldns_rdf_deep_free(b64_bignum);
+					goto error;
+				}
+				ldns_rdf_deep_free(b64_bignum);
+				ldns_buffer_printf(output, "\n");
+				ldns_buffer_printf(output, "PublicExponent: ");
+				i = (uint16_t)BN_bn2bin(rsa->e, bignum);
+				if (i > LDNS_MAX_KEYLEN) {
+					goto error;
+				}
+				b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+				if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+					ldns_rdf_deep_free(b64_bignum);
+					goto error;
+				}
+				ldns_rdf_deep_free(b64_bignum);
+				ldns_buffer_printf(output, "\n");
+
+				ldns_buffer_printf(output, "PrivateExponent: ");
+				if (rsa->d) {
+					i = (uint16_t)BN_bn2bin(rsa->d, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					ldns_buffer_printf(output, "(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Prime1: ");
+				if (rsa->p) {
+					i = (uint16_t)BN_bn2bin(rsa->p, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					ldns_buffer_printf(output, "(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Prime2: ");
+				if (rsa->q) {
+					i = (uint16_t)BN_bn2bin(rsa->q, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					ldns_buffer_printf(output, "(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Exponent1: ");
+				if (rsa->dmp1) {
+					i = (uint16_t)BN_bn2bin(rsa->dmp1, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					ldns_buffer_printf(output, "(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Exponent2: ");
+				if (rsa->dmq1) {
+					i = (uint16_t)BN_bn2bin(rsa->dmq1, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					ldns_buffer_printf(output, "(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Coefficient: ");
+				if (rsa->iqmp) {
+					i = (uint16_t)BN_bn2bin(rsa->iqmp, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					ldns_buffer_printf(output, "(Not available)\n");
+				}
+#endif /* splint */
+
+				RSA_free(rsa);
+				break;
+			case LDNS_SIGN_DSA:
+			case LDNS_SIGN_DSA_NSEC3:
+				dsa = ldns_key_dsa_key(k);
+
+				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
+				if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) {
+					ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
+				} else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) {
+					ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n");
+				}
+
+				/* print to buf, convert to bin, convert to b64,
+				 * print to buf */
+				ldns_buffer_printf(output, "Prime(p): ");
+#ifndef S_SPLINT_S
+				if (dsa->p) {
+					i = (uint16_t)BN_bn2bin(dsa->p, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					printf("(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Subprime(q): ");
+				if (dsa->q) {
+					i = (uint16_t)BN_bn2bin(dsa->q, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					printf("(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Base(g): ");
+				if (dsa->g) {
+					i = (uint16_t)BN_bn2bin(dsa->g, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					printf("(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Private_value(x): ");
+				if (dsa->priv_key) {
+					i = (uint16_t)BN_bn2bin(dsa->priv_key, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					printf("(Not available)\n");
+				}
+
+				ldns_buffer_printf(output, "Public_value(y): ");
+				if (dsa->pub_key) {
+					i = (uint16_t)BN_bn2bin(dsa->pub_key, bignum);
+					if (i > LDNS_MAX_KEYLEN) {
+						goto error;
+					}
+					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+						goto error;
+					}
+					ldns_rdf_deep_free(b64_bignum);
+					ldns_buffer_printf(output, "\n");
+				} else {
+					printf("(Not available)\n");
+				}
+#endif /* splint */
+				break;
+			case LDNS_SIGN_ECC_GOST:
+				/* no format defined, use blob */
+#if defined(HAVE_SSL) && defined(USE_GOST)
+				ldns_buffer_printf(output, "Private-key-format: v1.2\n");
+				ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
+				status = ldns_gost_key2buffer_str(output, 
+#ifndef S_SPLINT_S
+					k->_key.key
+#else
+					NULL
+#endif
+				);
+#else
+				goto error;
+#endif /* GOST */
+				break;
+			case LDNS_SIGN_ECDSAP256SHA256:
+			case LDNS_SIGN_ECDSAP384SHA384:
+#ifdef USE_ECDSA
+                                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
+				ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
+                                status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
+#ifndef S_SPLINT_S
+				ldns_buffer_printf(output, ")\n");
+                                if(k->_key.key) {
+                                        EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
+                                        const BIGNUM* b = EC_KEY_get0_private_key(ec);
+                                        ldns_buffer_printf(output, "PrivateKey: ");
+                                        i = (uint16_t)BN_bn2bin(b, bignum);
+                                        if (i > LDNS_MAX_KEYLEN) {
+                                                goto error;
+                                        }
+                                        b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
+                                        if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
+						ldns_rdf_deep_free(b64_bignum);
+                                                goto error;
+                                        }
+                                        ldns_rdf_deep_free(b64_bignum);
+				        ldns_buffer_printf(output, "\n");
+                                        /* down reference count in EC_KEY
+                                         * its still assigned to the PKEY */
+                                        EC_KEY_free(ec);
+                                }
+#endif /* splint */
+#else
+				goto error;
+#endif /* ECDSA */
+                                break;
+			case LDNS_SIGN_HMACMD5:
+				/* there's not much of a format defined for TSIG */
+				/* It's just a binary blob, Same for all algorithms */
+                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
+                ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n");
+				status = ldns_hmac_key2buffer_str(output, k);
+				break;
+			case LDNS_SIGN_HMACSHA1:
+		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
+		        ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n");
+				status = ldns_hmac_key2buffer_str(output, k);
+				break;
+			case LDNS_SIGN_HMACSHA256:
+		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
+		        ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n");
+				status = ldns_hmac_key2buffer_str(output, k);
+				break;
+		}
+#endif /* HAVE_SSL */
+	} else {
+		LDNS_FREE(bignum);
+		return ldns_buffer_status(output);
+	}
+	LDNS_FREE(bignum);
+	return status;
+
+#ifdef HAVE_SSL
+	/* compiles warn the label isn't used */
+error:
+	LDNS_FREE(bignum);
+	return LDNS_STATUS_ERR;
+#endif /* HAVE_SSL */
+
+}
+
+/*
+ * Zero terminate the buffer and copy data.
+ */
+char *
+ldns_buffer2str(ldns_buffer *buffer)
+{
+	char *str;
+
+	/* check if buffer ends with \0, if not, and
+	   if there is space, add it */
+	if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) {
+		if (!ldns_buffer_reserve(buffer, 1)) {
+			return NULL;
+		}
+		ldns_buffer_write_u8(buffer, (uint8_t) '\0');
+		if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
+			return NULL;
+		}
+	}
+
+	str = strdup((const char *)ldns_buffer_begin(buffer));
+        if(!str) {
+                return NULL;
+        }
+	return str;
+}
+
+/*
+ * Zero terminate the buffer and export data.
+ */
+char *
+ldns_buffer_export2str(ldns_buffer *buffer)
+{
+	/* Append '\0' as string terminator */
+	if (! ldns_buffer_reserve(buffer, 1)) {
+		return NULL;
+	}
+	ldns_buffer_write_u8(buffer, 0);
+
+	/* reallocate memory to the size of the string and export */
+	ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
+	return ldns_buffer_export(buffer);
+}
+
+char *
+ldns_rdf2str(const ldns_rdf *rdf)
+{
+	char *result = NULL;
+	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+
+	if (!tmp_buffer) {
+		return NULL;
+	}
+	if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
+		/* export and return string, destroy rest */
+		result = ldns_buffer_export2str(tmp_buffer);
+	}
+	ldns_buffer_free(tmp_buffer);
+	return result;
+}
+
+char *
+ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
+{
+	char *result = NULL;
+	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+
+	if (!tmp_buffer) {
+		return NULL;
+	}
+	if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
+		       	== LDNS_STATUS_OK) {
+		/* export and return string, destroy rest */
+		result = ldns_buffer_export2str(tmp_buffer);
+	}
+	ldns_buffer_free(tmp_buffer);
+	return result;
+}
+
+char *
+ldns_rr2str(const ldns_rr *rr)
+{
+	return ldns_rr2str_fmt(ldns_output_format_default, rr);
+}
+
+char *
+ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
+{
+	char *result = NULL;
+	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+
+	if (!tmp_buffer) {
+		return NULL;
+	}
+	if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
+		       	== LDNS_STATUS_OK) {
+		/* export and return string, destroy rest */
+		result = ldns_buffer_export2str(tmp_buffer);
+	}
+
+	ldns_buffer_free(tmp_buffer);
+	return result;
+}
+
+char *
+ldns_pkt2str(const ldns_pkt *pkt)
+{
+	return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
+}
+
+char *
+ldns_key2str(const ldns_key *k)
+{
+	char *result = NULL;
+	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+
+	if (!tmp_buffer) {
+		return NULL;
+	}
+	if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
+		/* export and return string, destroy rest */
+		result = ldns_buffer_export2str(tmp_buffer);
+	}
+	ldns_buffer_free(tmp_buffer);
+	return result;
+}
+
+char *
+ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
+{
+	char *result = NULL;
+	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+
+	if (!tmp_buffer) {
+		return NULL;
+	}
+	if (list) {
+		if (ldns_rr_list2buffer_str_fmt(
+				   tmp_buffer, fmt, list)
+			       	== LDNS_STATUS_OK) {
+		}
+	} else {
+		if (fmt == NULL) {
+			fmt = ldns_output_format_default;
+		}
+		if (fmt->flags & LDNS_COMMENT_NULLS) {
+			ldns_buffer_printf(tmp_buffer, "; (null)\n");
+		}
+	}
+
+	/* export and return string, destroy rest */
+	result = ldns_buffer_export2str(tmp_buffer);
+	ldns_buffer_free(tmp_buffer);
+	return result;
+}
+
+char *
+ldns_rr_list2str(const ldns_rr_list *list)
+{
+	return ldns_rr_list2str_fmt(ldns_output_format_default, list);
+}
+
+void
+ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
+{
+	char *str = ldns_rdf2str(rdf);
+	if (str) {
+		fprintf(output, "%s", str);
+	} else {
+		fprintf(output, ";Unable to convert rdf to string\n");
+	}
+	LDNS_FREE(str);
+}
+
+void
+ldns_rr_print_fmt(FILE *output,
+		const ldns_output_format *fmt, const ldns_rr *rr)
+{
+	char *str = ldns_rr2str_fmt(fmt, rr);
+	if (str) {
+		fprintf(output, "%s", str);
+	} else {
+		fprintf(output, ";Unable to convert rr to string\n");
+	}
+	LDNS_FREE(str);
+}
+
+void
+ldns_rr_print(FILE *output, const ldns_rr *rr)
+{
+	ldns_rr_print_fmt(output, ldns_output_format_default, rr);
+}
+
+void
+ldns_pkt_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_pkt *pkt)
+{
+	char *str = ldns_pkt2str_fmt(fmt, pkt);
+	if (str) {
+		fprintf(output, "%s", str);
+	} else {
+		fprintf(output, ";Unable to convert packet to string\n");
+	}
+	LDNS_FREE(str);
+}
+
+void
+ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
+{
+	ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
+}
+
+void
+ldns_rr_list_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_rr_list *lst)
+{
+	size_t i;
+	for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
+		ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
+	}
+}
+
+void
+ldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
+{
+	ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
+}
+
+void
+ldns_resolver_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_resolver *r)
+{
+	uint16_t i;
+	ldns_rdf **n;
+	ldns_rdf **s;
+	size_t *rtt;
+	if (!r) {
+		return;
+	}
+	n = ldns_resolver_nameservers(r);
+	s = ldns_resolver_searchlist(r);
+	rtt = ldns_resolver_rtt(r);
+
+	fprintf(output, "port: %d\n", (int)ldns_resolver_port(r));
+	fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r));
+	fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r));
+
+	fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r));
+	fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r));
+	fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
+	fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
+	fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
+	fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
+	fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
+	fprintf(output, "random: %d\n", ldns_resolver_random(r));
+	fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
+	fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r));
+	fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
+	fprintf(output, "trust anchors (%d listed):\n",
+		(int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
+	ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
+	fprintf(output, "tsig: %s %s\n",
+                ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
+                ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
+	fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
+
+	fprintf(output, "default domain: ");
+	ldns_rdf_print(output, ldns_resolver_domain(r));
+	fprintf(output, "\n");
+	fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
+
+	fprintf(output, "searchlist (%d listed):\n",  (int)ldns_resolver_searchlist_count(r));
+	for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
+		fprintf(output, "\t");
+		ldns_rdf_print(output, s[i]);
+		fprintf(output, "\n");
+	}
+	fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
+
+	fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
+	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
+		fprintf(output, "\t");
+		ldns_rdf_print(output, n[i]);
+
+		switch ((int)rtt[i]) {
+			case LDNS_RESOLV_RTT_MIN:
+			fprintf(output, " - reachable\n");
+			break;
+			case LDNS_RESOLV_RTT_INF:
+			fprintf(output, " - unreachable\n");
+			break;
+		}
+	}
+}
+
+void
+ldns_resolver_print(FILE *output, const ldns_resolver *r)
+{
+	ldns_resolver_print_fmt(output, ldns_output_format_default, r);
+}
+
+void
+ldns_zone_print_fmt(FILE *output, 
+		const ldns_output_format *fmt, const ldns_zone *z)
+{
+	if(ldns_zone_soa(z))
+		ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
+	ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
+}
+void
+ldns_zone_print(FILE *output, const ldns_zone *z)
+{
+	ldns_zone_print_fmt(output, ldns_output_format_default, z);
+}
diff --git a/ldns/src/host2wire.c b/ldns/src/host2wire.c
new file mode 100644
index 0000000..06f45ba
--- /dev/null
+++ b/ldns/src/host2wire.c
@@ -0,0 +1,494 @@
+/*
+ * host2wire.c
+ *
+ * conversion routines from the host to the wire format.
+ * This will usually just a re-ordering of the
+ * data (as we store it in network format)
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+ldns_status
+ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name)
+{
+	return ldns_dname2buffer_wire_compress(buffer, name, NULL);
+}
+
+ldns_status
+ldns_dname2buffer_wire_compress(ldns_buffer *buffer, const ldns_rdf *name, ldns_rbtree_t *compression_data)
+{
+	ldns_rbnode_t *node;
+	uint8_t *data;
+	size_t size;
+	ldns_rdf *label;
+	ldns_rdf *rest;
+	ldns_status s;
+
+	/* If no tree, just add the data */
+	if(!compression_data)
+	{
+		if (ldns_buffer_reserve(buffer, ldns_rdf_size(name)))
+		{
+			ldns_buffer_write(buffer, ldns_rdf_data(name), ldns_rdf_size(name));
+		}
+		return ldns_buffer_status(buffer);
+	}
+
+	/* No labels left, write final zero */
+	if(ldns_dname_label_count(name)==0)
+	{
+		if(ldns_buffer_reserve(buffer,1))
+		{
+			ldns_buffer_write_u8(buffer, 0);
+		}
+		return ldns_buffer_status(buffer);
+	}
+
+	/* Can we find the name in the tree? */
+	if((node = ldns_rbtree_search(compression_data, ldns_rdf_data(name))) != NULL)
+	{
+		/* Found */
+		uint16_t position = (uint16_t) (intptr_t) node->data | 0xC000;
+		if (ldns_buffer_reserve(buffer, 2))
+		{
+			ldns_buffer_write_u16(buffer, position);
+		}
+		return ldns_buffer_status(buffer);
+	}
+	else
+	{
+		/* Not found. Write cache entry, take off first label, write it, */
+		/* try again with the rest of the name. */
+		ldns_rbnode_t *node = LDNS_MALLOC(ldns_rbnode_t);
+		if(!node)
+		{
+			return LDNS_STATUS_MEM_ERR;
+		}
+		if (ldns_buffer_position(buffer) < 16384) {
+			node->key = strdup((const char *)ldns_rdf_data(name));
+			node->data = (void *) (intptr_t) ldns_buffer_position(buffer);
+			if(!ldns_rbtree_insert(compression_data,node))
+			{
+				/* fprintf(stderr,"Name not found but now it's there?\n"); */
+			}
+		}
+		label = ldns_dname_label(name, 0);
+		rest = ldns_dname_left_chop(name);
+		size = ldns_rdf_size(label) - 1; /* Don't want the final zero */
+		data = ldns_rdf_data(label);
+		if(ldns_buffer_reserve(buffer, size))
+		{
+			ldns_buffer_write(buffer, data, size);
+		}
+		ldns_rdf_deep_free(label);
+		s = ldns_dname2buffer_wire_compress(buffer, rest, compression_data);
+		ldns_rdf_deep_free(rest);
+		return s;
+	}
+}
+
+ldns_status
+ldns_rdf2buffer_wire(ldns_buffer *buffer, const ldns_rdf *rdf)
+{
+	return ldns_rdf2buffer_wire_compress(buffer, rdf, NULL);
+}
+
+ldns_status
+ldns_rdf2buffer_wire_compress(ldns_buffer *buffer, const ldns_rdf *rdf, ldns_rbtree_t *compression_data)
+{
+	/* If it's a DNAME, call that function to get compression */
+	if(compression_data && ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_DNAME)
+	{
+		return ldns_dname2buffer_wire_compress(buffer,rdf,compression_data);
+	}
+
+	if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
+		ldns_buffer_write(buffer, ldns_rdf_data(rdf), ldns_rdf_size(rdf));
+	}
+	return ldns_buffer_status(buffer);
+}
+
+ldns_status
+ldns_rdf2buffer_wire_canonical(ldns_buffer *buffer, const ldns_rdf *rdf)
+{
+	size_t i;
+	uint8_t *rdf_data;
+
+	if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_DNAME) {
+		if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
+			rdf_data = ldns_rdf_data(rdf);
+			for (i = 0; i < ldns_rdf_size(rdf); i++) {
+				ldns_buffer_write_u8(buffer,
+				    (uint8_t) LDNS_DNAME_NORMALIZE((int)rdf_data[i]));
+			}
+		}
+	} else {
+		/* direct copy for all other types */
+		if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
+			ldns_buffer_write(buffer,
+						   ldns_rdf_data(rdf),
+						   ldns_rdf_size(rdf));
+		}
+	}
+	return ldns_buffer_status(buffer);
+}
+
+/* convert a rr list to wireformat */
+ldns_status
+ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list)
+{
+	uint16_t rr_count;
+	uint16_t i;
+
+	rr_count = ldns_rr_list_rr_count(rr_list);
+	for(i = 0; i < rr_count; i++) {
+		(void)ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), 
+					  LDNS_SECTION_ANY);
+	}
+	return ldns_buffer_status(buffer);
+}
+
+
+ldns_status
+ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
+						const ldns_rr *rr,
+						int section)
+{
+	uint16_t i;
+	uint16_t rdl_pos = 0;
+	bool pre_rfc3597 = false;
+	switch (ldns_rr_get_type(rr)) {
+	case LDNS_RR_TYPE_NS:
+	case LDNS_RR_TYPE_MD:
+	case LDNS_RR_TYPE_MF:
+	case LDNS_RR_TYPE_CNAME:
+	case LDNS_RR_TYPE_SOA:
+	case LDNS_RR_TYPE_MB:
+	case LDNS_RR_TYPE_MG:
+	case LDNS_RR_TYPE_MR:
+	case LDNS_RR_TYPE_PTR:
+	case LDNS_RR_TYPE_HINFO:
+	case LDNS_RR_TYPE_MINFO:
+	case LDNS_RR_TYPE_MX:
+	case LDNS_RR_TYPE_RP:
+	case LDNS_RR_TYPE_AFSDB:
+	case LDNS_RR_TYPE_RT:
+	case LDNS_RR_TYPE_SIG:
+	case LDNS_RR_TYPE_PX:
+	case LDNS_RR_TYPE_NXT:
+	case LDNS_RR_TYPE_NAPTR:
+	case LDNS_RR_TYPE_KX:
+	case LDNS_RR_TYPE_SRV:
+	case LDNS_RR_TYPE_DNAME:
+	case LDNS_RR_TYPE_A6:
+	case LDNS_RR_TYPE_RRSIG:
+		pre_rfc3597 = true;
+		break;
+	default:
+		break;
+	}
+	
+	if (ldns_rr_owner(rr)) {
+		(void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_owner(rr));
+	}
+	
+	if (ldns_buffer_reserve(buffer, 4)) {
+		(void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
+		(void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
+	}
+
+	if (section != LDNS_SECTION_QUESTION) {
+		if (ldns_buffer_reserve(buffer, 6)) {
+			ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
+			/* remember pos for later */
+			rdl_pos = ldns_buffer_position(buffer);
+			ldns_buffer_write_u16(buffer, 0);
+		}	
+		for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+			if (pre_rfc3597) {
+				(void) ldns_rdf2buffer_wire_canonical(
+					buffer, ldns_rr_rdf(rr, i));
+			} else {
+				(void) ldns_rdf2buffer_wire(
+					buffer, ldns_rr_rdf(rr, i));
+			}
+		}
+		if (rdl_pos != 0) {
+			ldns_buffer_write_u16_at(buffer, rdl_pos,
+			                         ldns_buffer_position(buffer)
+		        	                   - rdl_pos - 2);
+		}
+	}
+	return ldns_buffer_status(buffer);
+}
+
+ldns_status
+ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
+{
+	return ldns_rr2buffer_wire_compress(buffer,rr,section,NULL);
+}
+
+ldns_status
+ldns_rr2buffer_wire_compress(ldns_buffer *buffer, const ldns_rr *rr, int section, ldns_rbtree_t *compression_data)
+{
+	uint16_t i;
+	uint16_t rdl_pos = 0;
+
+	if (ldns_rr_owner(rr)) {
+		(void) ldns_dname2buffer_wire_compress(buffer, ldns_rr_owner(rr), compression_data);
+	}
+	
+	if (ldns_buffer_reserve(buffer, 4)) {
+		(void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
+		(void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
+	}
+
+	if (section != LDNS_SECTION_QUESTION) {
+		if (ldns_buffer_reserve(buffer, 6)) {
+			ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
+			/* remember pos for later */
+			rdl_pos = ldns_buffer_position(buffer);
+			ldns_buffer_write_u16(buffer, 0);
+		}
+		if (LDNS_RR_COMPRESS ==
+		    ldns_rr_descript(ldns_rr_get_type(rr))->_compress) {
+
+			for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+				(void) ldns_rdf2buffer_wire_compress(buffer,
+				    ldns_rr_rdf(rr, i), compression_data);
+			}
+		} else {
+			for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+				(void) ldns_rdf2buffer_wire(
+				    buffer, ldns_rr_rdf(rr, i));
+			}
+		}
+		if (rdl_pos != 0) {
+			ldns_buffer_write_u16_at(buffer, rdl_pos,
+			                         ldns_buffer_position(buffer)
+		        	                   - rdl_pos - 2);
+		}
+	}
+	return ldns_buffer_status(buffer);
+}
+
+ldns_status
+ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
+{
+	uint16_t i;
+
+	/* it must be a sig RR */
+	if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
+		return LDNS_STATUS_ERR;
+	}
+	
+	/* Convert all the rdfs, except the actual signature data
+	 * rdf number 8  - the last, hence: -1 */
+	for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
+		(void) ldns_rdf2buffer_wire_canonical(buffer, 
+				ldns_rr_rdf(rr, i));
+	}
+
+	return ldns_buffer_status(buffer);
+}
+
+ldns_status
+ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
+{
+	uint16_t i;
+
+	/* convert all the rdf's */
+	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+		(void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr,i));
+	}
+	return ldns_buffer_status(buffer);
+}
+
+/*
+ * Copies the packet header data to the buffer in wire format
+ */
+static ldns_status
+ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
+{
+	uint8_t flags;
+	uint16_t arcount;
+
+	if (ldns_buffer_reserve(buffer, 12)) {
+		ldns_buffer_write_u16(buffer, ldns_pkt_id(packet));
+		
+		flags = ldns_pkt_qr(packet) << 7
+		        | ldns_pkt_get_opcode(packet) << 3
+		        | ldns_pkt_aa(packet) << 2
+		        | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet);
+		ldns_buffer_write_u8(buffer, flags);
+		
+		flags = ldns_pkt_ra(packet) << 7
+		        /*| ldns_pkt_z(packet) << 6*/
+		        | ldns_pkt_ad(packet) << 5
+		        | ldns_pkt_cd(packet) << 4
+			| ldns_pkt_get_rcode(packet);
+		ldns_buffer_write_u8(buffer, flags);
+		
+		ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet));
+		ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet));
+		ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet));
+		/* add EDNS0 and TSIG to additional if they are there */
+		arcount = ldns_pkt_arcount(packet);
+		if (ldns_pkt_tsig(packet)) {
+			arcount++;
+		}
+		if (ldns_pkt_edns(packet)) {
+			arcount++;
+		}
+		ldns_buffer_write_u16(buffer, arcount);
+	}
+	
+	return ldns_buffer_status(buffer);
+}
+
+void
+compression_node_free(ldns_rbnode_t *node, void *arg)
+{
+	(void)arg; /* Yes, dear compiler, it is used */
+	free((void *)node->key);
+	LDNS_FREE(node);
+}
+
+ldns_status
+ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
+{
+	ldns_rr_list *rr_list;
+	uint16_t i;
+
+	/* edns tmp vars */
+	ldns_rr *edns_rr;
+	uint8_t edata[4];
+
+	ldns_rbtree_t *compression_data = ldns_rbtree_create((int (*)(const void *, const void *))strcasecmp);
+	
+	(void) ldns_hdr2buffer_wire(buffer, packet);
+
+	rr_list = ldns_pkt_question(packet);
+	if (rr_list) {
+		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
+			(void) ldns_rr2buffer_wire_compress(buffer, 
+			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION, compression_data);
+		}
+	}
+	rr_list = ldns_pkt_answer(packet);
+	if (rr_list) {
+		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
+			(void) ldns_rr2buffer_wire_compress(buffer, 
+			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER, compression_data);
+		}
+	}
+	rr_list = ldns_pkt_authority(packet);
+	if (rr_list) {
+		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
+			(void) ldns_rr2buffer_wire_compress(buffer, 
+			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY, compression_data);
+		}
+	}
+	rr_list = ldns_pkt_additional(packet);
+	if (rr_list) {
+		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
+			(void) ldns_rr2buffer_wire_compress(buffer, 
+			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL, compression_data);
+		}
+	}
+	
+	/* add EDNS to additional if it is needed */
+	if (ldns_pkt_edns(packet)) {
+		edns_rr = ldns_rr_new();
+		if(!edns_rr) return LDNS_STATUS_MEM_ERR;
+		ldns_rr_set_owner(edns_rr,
+				ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
+		ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
+		ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
+		edata[0] = ldns_pkt_edns_extended_rcode(packet);
+		edata[1] = ldns_pkt_edns_version(packet);
+		ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
+		ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
+		/* don't forget to add the edns rdata (if any) */
+		if (packet->_edns_data)
+			ldns_rr_push_rdf (edns_rr, packet->_edns_data);
+		(void)ldns_rr2buffer_wire_compress(buffer, edns_rr, LDNS_SECTION_ADDITIONAL, compression_data);
+		/* take the edns rdata back out of the rr before we free rr */
+		if (packet->_edns_data)
+			(void)ldns_rr_pop_rdf (edns_rr);
+		ldns_rr_free(edns_rr);
+	}
+	
+	/* add TSIG to additional if it is there */
+	if (ldns_pkt_tsig(packet)) {
+		(void) ldns_rr2buffer_wire_compress(buffer,
+		                           ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL, compression_data);
+	}
+
+	ldns_traverse_postorder(compression_data,compression_node_free,NULL);
+	ldns_rbtree_free(compression_data);
+
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
+{
+	ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	ldns_status status;
+	*result_size = 0;
+	*dest = NULL;
+	if(!buffer) return LDNS_STATUS_MEM_ERR;
+	
+	status = ldns_rdf2buffer_wire(buffer, rdf);
+	if (status == LDNS_STATUS_OK) {
+		*result_size =  ldns_buffer_position(buffer);
+		*dest = (uint8_t *) ldns_buffer_export(buffer);
+	}
+	ldns_buffer_free(buffer);
+	return status;
+}
+
+ldns_status
+ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size)
+{
+	ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	ldns_status status;
+	*result_size = 0;
+	*dest = NULL;
+	if(!buffer) return LDNS_STATUS_MEM_ERR;
+	
+	status = ldns_rr2buffer_wire(buffer, rr, section);
+	if (status == LDNS_STATUS_OK) {
+		*result_size =  ldns_buffer_position(buffer);
+		*dest = (uint8_t *) ldns_buffer_export(buffer);
+	}
+	ldns_buffer_free(buffer);
+	return status;
+}
+
+ldns_status
+ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
+{
+	ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	ldns_status status;
+	*result_size = 0;
+	*dest = NULL;
+	if(!buffer) return LDNS_STATUS_MEM_ERR;
+	
+	status = ldns_pkt2buffer_wire(buffer, packet);
+	if (status == LDNS_STATUS_OK) {
+		*result_size =  ldns_buffer_position(buffer);
+		*dest = (uint8_t *) ldns_buffer_export(buffer);
+	}
+	ldns_buffer_free(buffer);
+	return status;
+}
diff --git a/ldns/src/keys.c b/ldns/src/keys.c
new file mode 100644
index 0000000..8b43821
--- /dev/null
+++ b/ldns/src/keys.c
@@ -0,0 +1,1726 @@
+/*
+ * keys.c handle private keys for use in DNSSEC
+ *
+ * This module should hide some of the openSSL complexities
+ * and give a general interface for private keys and hmac
+ * handling
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#ifdef HAVE_SSL
+#include <openssl/ssl.h>
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+#endif /* HAVE_SSL */
+
+ldns_lookup_table ldns_signing_algorithms[] = {
+        { LDNS_SIGN_RSAMD5, "RSAMD5" },
+        { LDNS_SIGN_RSASHA1, "RSASHA1" },
+        { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
+#ifdef USE_SHA2
+        { LDNS_SIGN_RSASHA256, "RSASHA256" },
+        { LDNS_SIGN_RSASHA512, "RSASHA512" },
+#endif
+#ifdef USE_GOST
+        { LDNS_SIGN_ECC_GOST, "ECC-GOST" },
+#endif
+#ifdef USE_ECDSA
+        { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" },
+        { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" },
+#endif
+        { LDNS_SIGN_DSA, "DSA" },
+        { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" },
+        { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
+        { LDNS_SIGN_HMACSHA1, "hmac-sha1" },
+        { LDNS_SIGN_HMACSHA256, "hmac-sha256" },
+        { 0, NULL }
+};
+
+ldns_key_list *
+ldns_key_list_new(void)
+{
+	ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list);
+	if (!key_list) {
+		return NULL;
+	} else {
+		key_list->_key_count = 0;
+		key_list->_keys = NULL;
+		return key_list;
+	}
+}
+
+ldns_key *
+ldns_key_new(void)
+{
+	ldns_key *newkey;
+
+	newkey = LDNS_MALLOC(ldns_key);
+	if (!newkey) {
+		return NULL;
+	} else {
+		/* some defaults - not sure wether to do this */
+		ldns_key_set_use(newkey, true);
+		ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY);
+		ldns_key_set_origttl(newkey, 0);
+		ldns_key_set_keytag(newkey, 0);
+		ldns_key_set_inception(newkey, 0);
+		ldns_key_set_expiration(newkey, 0);
+		ldns_key_set_pubkey_owner(newkey, NULL);
+#ifdef HAVE_SSL
+		ldns_key_set_evp_key(newkey, NULL);
+#endif /* HAVE_SSL */
+		ldns_key_set_hmac_key(newkey, NULL);
+		ldns_key_set_external_key(newkey, NULL);
+		return newkey;
+	}
+}
+
+ldns_status
+ldns_key_new_frm_fp(ldns_key **k, FILE *fp)
+{
+	return ldns_key_new_frm_fp_l(k, fp, NULL);
+}
+
+#ifdef HAVE_SSL
+ldns_status
+ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
+{
+	ldns_key *k;
+
+	k = ldns_key_new();
+        if(!k) return LDNS_STATUS_MEM_ERR;
+#ifndef S_SPLINT_S
+	k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL);
+        if(!k->_key.key) {
+                ldns_key_free(k);
+                return LDNS_STATUS_ERR;
+        }
+	ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg);
+	if (!k->_key.key) {
+                ldns_key_free(k);
+		return LDNS_STATUS_ENGINE_KEY_NOT_LOADED;
+	} 
+#endif /* splint */
+	*key = k;
+	return LDNS_STATUS_OK;
+}
+#endif
+
+#ifdef USE_GOST
+/** store GOST engine reference loaded into OpenSSL library */
+ENGINE* ldns_gost_engine = NULL;
+
+int
+ldns_key_EVP_load_gost_id(void)
+{
+	static int gost_id = 0;
+	const EVP_PKEY_ASN1_METHOD* meth;
+	ENGINE* e;
+
+	if(gost_id) return gost_id;
+
+	/* see if configuration loaded gost implementation from other engine*/
+	meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
+	if(meth) {
+		EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
+		return gost_id;
+	}
+
+	/* see if engine can be loaded already */
+	e = ENGINE_by_id("gost");
+	if(!e) {
+		/* load it ourself, in case statically linked */
+		ENGINE_load_builtin_engines();
+		ENGINE_load_dynamic();
+		e = ENGINE_by_id("gost");
+	}
+	if(!e) {
+		/* no gost engine in openssl */
+		return 0;
+	}
+	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
+		ENGINE_finish(e);
+		ENGINE_free(e);
+		return 0;
+	}
+
+	meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
+	if(!meth) {
+		/* algo not found */
+		ENGINE_finish(e);
+		ENGINE_free(e);
+		return 0;
+	}
+        /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
+         * on some platforms this frees up the meth and unloads gost stuff */
+        ldns_gost_engine = e;
+	
+	EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
+	return gost_id;
+} 
+
+void ldns_key_EVP_unload_gost(void)
+{
+        if(ldns_gost_engine) {
+                ENGINE_finish(ldns_gost_engine);
+                ENGINE_free(ldns_gost_engine);
+                ldns_gost_engine = NULL;
+        }
+}
+
+/** read GOST private key */
+static EVP_PKEY*
+ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr)
+{
+	char token[16384];
+	const unsigned char* pp;
+	int gost_id;
+	EVP_PKEY* pkey;
+	ldns_rdf* b64rdf = NULL;
+
+	gost_id = ldns_key_EVP_load_gost_id();
+	if(!gost_id)
+		return NULL;
+
+	if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n", 
+		sizeof(token), line_nr) == -1)
+		return NULL;
+	while(strlen(token) < 96) {
+		/* read more b64 from the file, b64 split on multiple lines */
+		if(ldns_fget_token_l(fp, token+strlen(token), "\n",
+			sizeof(token)-strlen(token), line_nr) == -1)
+			return NULL;
+	}
+	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
+		return NULL;
+	pp = (unsigned char*)ldns_rdf_data(b64rdf);
+	pkey = d2i_PrivateKey(gost_id, NULL, &pp, (int)ldns_rdf_size(b64rdf));
+	ldns_rdf_deep_free(b64rdf);
+	return pkey;
+}
+#endif
+
+#ifdef USE_ECDSA
+/** calculate public key from private key */
+static int
+ldns_EC_KEY_calc_public(EC_KEY* ec)
+{
+        EC_POINT* pub_key;
+        const EC_GROUP* group;
+        group = EC_KEY_get0_group(ec);
+        pub_key = EC_POINT_new(group);
+        if(!pub_key) return 0;
+        if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
+                EC_POINT_free(pub_key);
+                return 0;
+        }
+        if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec),
+                NULL, NULL, NULL)) {
+                EC_POINT_free(pub_key);
+                return 0;
+        }
+        if(EC_KEY_set_public_key(ec, pub_key) == 0) {
+                EC_POINT_free(pub_key);
+                return 0;
+        }
+        EC_POINT_free(pub_key);
+        return 1;
+}
+
+/** read ECDSA private key */
+static EVP_PKEY*
+ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
+{
+	char token[16384];
+        ldns_rdf* b64rdf = NULL;
+        unsigned char* pp;
+        BIGNUM* bn;
+        EVP_PKEY* evp_key;
+        EC_KEY* ec;
+	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 
+		sizeof(token), line_nr) == -1)
+		return NULL;
+	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
+		return NULL;
+        pp = (unsigned char*)ldns_rdf_data(b64rdf);
+
+        if(alg == LDNS_ECDSAP256SHA256)
+                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+        else if(alg == LDNS_ECDSAP384SHA384)
+                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
+        else    ec = NULL;
+        if(!ec) {
+	        ldns_rdf_deep_free(b64rdf);
+                return NULL;
+        }
+	bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL);
+	ldns_rdf_deep_free(b64rdf);
+        if(!bn) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        EC_KEY_set_private_key(ec, bn);
+        BN_free(bn);
+        if(!ldns_EC_KEY_calc_public(ec)) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+
+        evp_key = EVP_PKEY_new();
+        if(!evp_key) {
+                EC_KEY_free(ec);
+                return NULL;
+        }
+        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
+		EVP_PKEY_free(evp_key);
+                EC_KEY_free(ec);
+                return NULL;
+	}
+        return evp_key;
+}
+#endif
+	
+ldns_status
+ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
+{
+	ldns_key *k;
+	char *d;
+	ldns_signing_algorithm alg;
+	ldns_rr *key_rr;
+#ifdef HAVE_SSL
+	RSA *rsa;
+	DSA *dsa;
+	unsigned char *hmac;
+	size_t hmac_size;
+#endif /* HAVE_SSL */
+
+	k = ldns_key_new();
+
+	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
+	if (!k || !d) {
+                ldns_key_free(k);
+                LDNS_FREE(d);
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	alg = 0;
+
+	/* the file is highly structured. Do this in sequence */
+	/* RSA:
+	 * Private-key-format: v1.x.
+ 	 * Algorithm: 1 (RSA)
+
+	 */
+	/* get the key format version number */
+	if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n",
+				LDNS_MAX_LINELEN, line_nr) == -1) {
+		/* no version information */
+                ldns_key_free(k);
+                LDNS_FREE(d);
+		return LDNS_STATUS_SYNTAX_ERR;
+	}
+	if (strncmp(d, "v1.", 3) != 0) {
+                ldns_key_free(k);
+                LDNS_FREE(d);
+		return LDNS_STATUS_SYNTAX_VERSION_ERR;
+	}
+
+	/* get the algorithm type, our file function strip ( ) so there are
+	 * not in the return string! */
+	if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n",
+				LDNS_MAX_LINELEN, line_nr) == -1) {
+		/* no alg information */
+                ldns_key_free(k);
+                LDNS_FREE(d);
+		return LDNS_STATUS_SYNTAX_ALG_ERR;
+	}
+
+	if (strncmp(d, "1 RSA", 2) == 0) {
+		alg = LDNS_SIGN_RSAMD5;
+	}
+	if (strncmp(d, "2 DH", 2) == 0) {
+		alg = (ldns_signing_algorithm)LDNS_DH;
+	}
+	if (strncmp(d, "3 DSA", 2) == 0) {
+		alg = LDNS_SIGN_DSA;
+	}
+	if (strncmp(d, "4 ECC", 2) == 0) {
+		alg = (ldns_signing_algorithm)LDNS_ECC;
+	}
+	if (strncmp(d, "5 RSASHA1", 2) == 0) {
+		alg = LDNS_SIGN_RSASHA1;
+	}
+	if (strncmp(d, "6 DSA", 2) == 0) {
+		alg = LDNS_SIGN_DSA_NSEC3;
+	}
+	if (strncmp(d, "7 RSASHA1", 2) == 0) {
+		alg = LDNS_SIGN_RSASHA1_NSEC3;
+	}
+
+	if (strncmp(d, "8 RSASHA256", 2) == 0) {
+#ifdef USE_SHA2
+		alg = LDNS_SIGN_RSASHA256;
+#else
+# ifdef STDERR_MSGS
+		fprintf(stderr, "Warning: SHA256 not compiled into this ");
+		fprintf(stderr, "version of ldns\n");
+# endif
+#endif
+	}
+	if (strncmp(d, "10 RSASHA512", 3) == 0) {
+#ifdef USE_SHA2
+		alg = LDNS_SIGN_RSASHA512;
+#else
+# ifdef STDERR_MSGS
+		fprintf(stderr, "Warning: SHA512 not compiled into this ");
+		fprintf(stderr, "version of ldns\n");
+# endif
+#endif
+	}
+	if (strncmp(d, "12 ECC-GOST", 3) == 0) {
+#ifdef USE_GOST
+		alg = LDNS_SIGN_ECC_GOST;
+#else
+# ifdef STDERR_MSGS
+		fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
+		fprintf(stderr, "version of ldns, use --enable-gost\n");
+# endif
+#endif
+	}
+	if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
+#ifdef USE_ECDSA
+                alg = LDNS_SIGN_ECDSAP256SHA256;
+#else
+# ifdef STDERR_MSGS
+		fprintf(stderr, "Warning: ECDSA not compiled into this ");
+		fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
+# endif
+#endif
+        }
+	if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
+#ifdef USE_ECDSA
+                alg = LDNS_SIGN_ECDSAP384SHA384;
+#else
+# ifdef STDERR_MSGS
+		fprintf(stderr, "Warning: ECDSA not compiled into this ");
+		fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
+# endif
+#endif
+        }
+	if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
+		alg = LDNS_SIGN_HMACMD5;
+	}
+	if (strncmp(d, "158 HMAC-SHA1", 4) == 0) {
+		alg = LDNS_SIGN_HMACSHA1;
+	}
+	if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
+		alg = LDNS_SIGN_HMACSHA256;
+	}
+
+	LDNS_FREE(d);
+
+	switch(alg) {
+		case LDNS_SIGN_RSAMD5:
+		case LDNS_SIGN_RSASHA1:
+		case LDNS_SIGN_RSASHA1_NSEC3:
+#ifdef USE_SHA2
+		case LDNS_SIGN_RSASHA256:
+		case LDNS_SIGN_RSASHA512:
+#endif
+			ldns_key_set_algorithm(k, alg);
+#ifdef HAVE_SSL
+			rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
+			if (!rsa) {
+				ldns_key_free(k);
+				return LDNS_STATUS_ERR;
+			}
+			ldns_key_assign_rsa_key(k, rsa);
+#endif /* HAVE_SSL */
+			break;
+		case LDNS_SIGN_DSA:
+		case LDNS_SIGN_DSA_NSEC3:
+			ldns_key_set_algorithm(k, alg);
+#ifdef HAVE_SSL
+			dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
+			if (!dsa) {
+				ldns_key_free(k);
+				return LDNS_STATUS_ERR;
+			}
+			ldns_key_assign_dsa_key(k, dsa);
+#endif /* HAVE_SSL */
+			break;
+		case LDNS_SIGN_HMACMD5:
+		case LDNS_SIGN_HMACSHA1:
+		case LDNS_SIGN_HMACSHA256:
+			ldns_key_set_algorithm(k, alg);
+#ifdef HAVE_SSL
+			hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
+			if (!hmac) {
+				ldns_key_free(k);
+				return LDNS_STATUS_ERR;
+			}
+			ldns_key_set_hmac_size(k, hmac_size);
+			ldns_key_set_hmac_key(k, hmac);
+#endif /* HAVE_SSL */
+			break;
+		case LDNS_SIGN_ECC_GOST:
+			ldns_key_set_algorithm(k, alg);
+#if defined(HAVE_SSL) && defined(USE_GOST)
+                        if(!ldns_key_EVP_load_gost_id()) {
+				ldns_key_free(k);
+                                return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
+                        }
+			ldns_key_set_evp_key(k, 
+				ldns_key_new_frm_fp_gost_l(fp, line_nr));
+#ifndef S_SPLINT_S
+			if(!k->_key.key) {
+				ldns_key_free(k);
+				return LDNS_STATUS_ERR;
+			}
+#endif /* splint */
+#endif
+			break;
+#ifdef USE_ECDSA
+               case LDNS_SIGN_ECDSAP256SHA256:
+               case LDNS_SIGN_ECDSAP384SHA384:
+                        ldns_key_set_algorithm(k, alg);
+                        ldns_key_set_evp_key(k,
+                                ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr));
+#ifndef S_SPLINT_S
+			if(!k->_key.key) {
+				ldns_key_free(k);
+				return LDNS_STATUS_ERR;
+			}
+#endif /* splint */
+			break;
+#endif
+		default:
+			ldns_key_free(k);
+			return LDNS_STATUS_SYNTAX_ALG_ERR;
+	}
+	key_rr = ldns_key2rr(k);
+	ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
+	ldns_rr_free(key_rr);
+
+	if (key) {
+		*key = k;
+		return LDNS_STATUS_OK;
+	}
+	ldns_key_free(k);
+	return LDNS_STATUS_ERR;
+}
+
+#ifdef HAVE_SSL
+RSA *
+ldns_key_new_frm_fp_rsa(FILE *f)
+{
+	return ldns_key_new_frm_fp_rsa_l(f, NULL);
+}
+
+RSA *
+ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
+{
+	/* we parse
+ 	 * Modulus:
+ 	 * PublicExponent:
+ 	 * PrivateExponent:
+ 	 * Prime1:
+ 	 * Prime2:
+ 	 * Exponent1:
+ 	 * Exponent2:
+ 	 * Coefficient:
+	 *
+	 * man 3 RSA:
+	 *
+	 * struct
+         *     {
+         *     BIGNUM *n;              // public modulus
+         *     BIGNUM *e;              // public exponent
+         *     BIGNUM *d;              // private exponent
+         *     BIGNUM *p;              // secret prime factor
+         *     BIGNUM *q;              // secret prime factor
+         *     BIGNUM *dmp1;           // d mod (p-1)
+         *     BIGNUM *dmq1;           // d mod (q-1)
+         *     BIGNUM *iqmp;           // q^-1 mod p
+         *     // ...
+	 *
+	 */
+	char *d;
+	RSA *rsa;
+	uint8_t *buf;
+	int i;
+
+	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
+	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
+	rsa = RSA_new();
+	if (!d || !rsa || !buf) {
+                goto error;
+	}
+
+	/* I could use functions again, but that seems an overkill,
+	 * allthough this also looks tedious
+	 */
+
+	/* Modules, rsa->n */
+	if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+#ifndef S_SPLINT_S
+	rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!rsa->n) {
+		goto error;
+	}
+
+	/* PublicExponent, rsa->e */
+	if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!rsa->e) {
+		goto error;
+	}
+
+	/* PrivateExponent, rsa->d */
+	if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!rsa->d) {
+		goto error;
+	}
+
+	/* Prime1, rsa->p */
+	if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!rsa->p) {
+		goto error;
+	}
+
+	/* Prime2, rsa->q */
+	if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!rsa->q) {
+		goto error;
+	}
+
+	/* Exponent1, rsa->dmp1 */
+	if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!rsa->dmp1) {
+		goto error;
+	}
+
+	/* Exponent2, rsa->dmq1 */
+	if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!rsa->dmq1) {
+		goto error;
+	}
+
+	/* Coefficient, rsa->iqmp */
+	if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!rsa->iqmp) {
+		goto error;
+	}
+#endif /* splint */
+
+	LDNS_FREE(buf);
+	LDNS_FREE(d);
+	return rsa;
+
+error:
+	RSA_free(rsa);
+	LDNS_FREE(d);
+	LDNS_FREE(buf);
+	return NULL;
+}
+
+DSA *
+ldns_key_new_frm_fp_dsa(FILE *f)
+{
+	return ldns_key_new_frm_fp_dsa_l(f, NULL);
+}
+
+DSA *
+ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr))
+{
+	int i;
+	char *d;
+	DSA *dsa;
+	uint8_t *buf;
+
+	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
+	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
+	dsa = DSA_new();
+	if (!d || !dsa || !buf) {
+                goto error;
+	}
+
+	/* the line parser removes the () from the input... */
+
+	/* Prime, dsa->p */
+	if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+#ifndef S_SPLINT_S
+	dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!dsa->p) {
+		goto error;
+	}
+
+	/* Subprime, dsa->q */
+	if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!dsa->q) {
+		goto error;
+	}
+
+	/* Base, dsa->g */
+	if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!dsa->g) {
+		goto error;
+	}
+
+	/* Private key, dsa->priv_key */
+	if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!dsa->priv_key) {
+		goto error;
+	}
+
+	/* Public key, dsa->priv_key */
+	if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
+	dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
+	if (!dsa->pub_key) {
+		goto error;
+	}
+#endif /* splint */
+
+	LDNS_FREE(buf);
+	LDNS_FREE(d);
+
+	return dsa;
+
+error:
+	LDNS_FREE(d);
+	LDNS_FREE(buf);
+        DSA_free(dsa);
+	return NULL;
+}
+
+unsigned char *
+ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size)
+{
+	return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size);
+}
+
+unsigned char *
+ldns_key_new_frm_fp_hmac_l( FILE *f
+			  , ATTR_UNUSED(int *line_nr)
+			  , size_t *hmac_size
+			  )
+{
+	size_t i, bufsz;
+	char d[LDNS_MAX_LINELEN];
+	unsigned char *buf = NULL;
+
+	if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
+		goto error;
+	}
+	bufsz = ldns_b64_ntop_calculate_size(strlen(d));
+	buf = LDNS_XMALLOC(unsigned char, bufsz);
+	i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz);
+
+	*hmac_size = i;
+	return buf;
+
+	error:
+	LDNS_FREE(buf);
+	*hmac_size = 0;
+	return NULL;
+}
+#endif /* HAVE_SSL */
+
+#ifdef USE_GOST
+static EVP_PKEY*
+ldns_gen_gost_key(void)
+{
+	EVP_PKEY_CTX* ctx;
+	EVP_PKEY* p = NULL;
+	int gost_id = ldns_key_EVP_load_gost_id();
+	if(!gost_id)
+		return NULL;
+	ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
+	if(!ctx) {
+		/* the id should be available now */
+		return NULL;
+	}
+	if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
+		/* cannot set paramset */
+		EVP_PKEY_CTX_free(ctx);
+		return NULL;
+	}
+
+	if(EVP_PKEY_keygen_init(ctx) <= 0) {
+		EVP_PKEY_CTX_free(ctx);
+		return NULL;
+	}
+	if(EVP_PKEY_keygen(ctx, &p) <= 0) {
+		EVP_PKEY_free(p);
+		EVP_PKEY_CTX_free(ctx);
+		return NULL;
+	}
+	EVP_PKEY_CTX_free(ctx);
+	return p;
+}
+#endif
+
+ldns_key *
+ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
+{
+	ldns_key *k;
+#ifdef HAVE_SSL
+	DSA *d;
+	RSA *r;
+#  ifdef USE_ECDSA
+        EC_KEY *ec = NULL;
+#  endif
+#else
+	int i;
+	uint16_t offset = 0;
+#endif
+	unsigned char *hmac;
+
+	k = ldns_key_new();
+	if (!k) {
+		return NULL;
+	}
+	switch(alg) {
+		case LDNS_SIGN_RSAMD5:
+		case LDNS_SIGN_RSASHA1:
+		case LDNS_SIGN_RSASHA1_NSEC3:
+		case LDNS_SIGN_RSASHA256:
+		case LDNS_SIGN_RSASHA512:
+#ifdef HAVE_SSL
+			r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
+                        if(!r) {
+				ldns_key_free(k);
+				return NULL;
+			}
+			if (RSA_check_key(r) != 1) {
+				ldns_key_free(k);
+				return NULL;
+			}
+			ldns_key_set_rsa_key(k, r);
+			RSA_free(r);
+#endif /* HAVE_SSL */
+			break;
+		case LDNS_SIGN_DSA:
+		case LDNS_SIGN_DSA_NSEC3:
+#ifdef HAVE_SSL
+			d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
+			if (!d) {
+				ldns_key_free(k);
+				return NULL;
+			}
+			if (DSA_generate_key(d) != 1) {
+				ldns_key_free(k);
+				return NULL;
+			}
+			ldns_key_set_dsa_key(k, d);
+			DSA_free(d);
+#endif /* HAVE_SSL */
+			break;
+		case LDNS_SIGN_HMACMD5:
+		case LDNS_SIGN_HMACSHA1:
+		case LDNS_SIGN_HMACSHA256:
+#ifdef HAVE_SSL
+#ifndef S_SPLINT_S
+			k->_key.key = NULL;
+#endif /* splint */
+#endif /* HAVE_SSL */
+			size = size / 8;
+			ldns_key_set_hmac_size(k, size);
+
+			hmac = LDNS_XMALLOC(unsigned char, size);
+                        if(!hmac) {
+				ldns_key_free(k);
+				return NULL;
+                        }
+#ifdef HAVE_SSL
+			if (RAND_bytes(hmac, (int) size) != 1) {
+				LDNS_FREE(hmac);
+				ldns_key_free(k);
+				return NULL;
+			}
+#else
+			while (offset + sizeof(i) < size) {
+			  i = random();
+			  memcpy(&hmac[offset], &i, sizeof(i));
+			  offset += sizeof(i);
+			}
+			if (offset < size) {
+			  i = random();
+			  memcpy(&hmac[offset], &i, size - offset);
+			}
+#endif /* HAVE_SSL */
+			ldns_key_set_hmac_key(k, hmac);
+
+			ldns_key_set_flags(k, 0);
+			break;
+		case LDNS_SIGN_ECC_GOST:
+#if defined(HAVE_SSL) && defined(USE_GOST)
+			ldns_key_set_evp_key(k, ldns_gen_gost_key());
+#ifndef S_SPLINT_S
+                        if(!k->_key.key) {
+                                ldns_key_free(k);
+                                return NULL;
+                        }
+#endif /* splint */
+#else
+			ldns_key_free(k);
+			return NULL;
+#endif /* HAVE_SSL and USE_GOST */
+                        break;
+                case LDNS_SIGN_ECDSAP256SHA256:
+                case LDNS_SIGN_ECDSAP384SHA384:
+#ifdef USE_ECDSA
+                        if(alg == LDNS_SIGN_ECDSAP256SHA256)
+                                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+                        else if(alg == LDNS_SIGN_ECDSAP384SHA384)
+                                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
+                        if(!ec) {
+                                ldns_key_free(k);
+                                return NULL;
+                        }
+                        if(!EC_KEY_generate_key(ec)) {
+                                ldns_key_free(k);
+                                EC_KEY_free(ec);
+                                return NULL;
+                        }
+#ifndef S_SPLINT_S
+                        k->_key.key = EVP_PKEY_new();
+                        if(!k->_key.key) {
+                                ldns_key_free(k);
+                                EC_KEY_free(ec);
+                                return NULL;
+                        }
+                        if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) {
+                                ldns_key_free(k);
+                                EC_KEY_free(ec);
+                                return NULL;
+			}
+#endif /* splint */
+#else
+			ldns_key_free(k);
+			return NULL;
+#endif /* ECDSA */
+			break;
+	}
+	ldns_key_set_algorithm(k, alg);
+	return k;
+}
+
+void
+ldns_key_print(FILE *output, const ldns_key *k)
+{
+	char *str = ldns_key2str(k);
+	if (str) {
+                fprintf(output, "%s", str);
+        } else {
+                fprintf(output, "Unable to convert private key to string\n");
+        }
+        LDNS_FREE(str);
+}
+
+
+void
+ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l)
+{
+	k->_alg = l;
+}
+
+void
+ldns_key_set_flags(ldns_key *k, uint16_t f)
+{
+	k->_extra.dnssec.flags = f;
+}
+
+#ifdef HAVE_SSL
+#ifndef S_SPLINT_S
+void
+ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
+{
+	k->_key.key = e;
+}
+
+void
+ldns_key_set_rsa_key(ldns_key *k, RSA *r)
+{
+	EVP_PKEY *key = EVP_PKEY_new();
+	EVP_PKEY_set1_RSA(key, r);
+	k->_key.key = key;
+}
+
+void
+ldns_key_set_dsa_key(ldns_key *k, DSA *d)
+{
+	EVP_PKEY *key = EVP_PKEY_new();
+	EVP_PKEY_set1_DSA(key, d);
+	k->_key.key  = key;
+}
+
+void
+ldns_key_assign_rsa_key(ldns_key *k, RSA *r)
+{
+	EVP_PKEY *key = EVP_PKEY_new();
+	EVP_PKEY_assign_RSA(key, r);
+	k->_key.key = key;
+}
+
+void
+ldns_key_assign_dsa_key(ldns_key *k, DSA *d)
+{
+	EVP_PKEY *key = EVP_PKEY_new();
+	EVP_PKEY_assign_DSA(key, d);
+	k->_key.key  = key;
+}
+#endif /* splint */
+#endif /* HAVE_SSL */
+
+void
+ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
+{
+	k->_key.hmac.key = hmac;
+}
+
+void
+ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
+{
+	k->_key.hmac.size = hmac_size;
+}
+
+void
+ldns_key_set_external_key(ldns_key *k, void *external_key)
+{
+	k->_key.external_key = external_key;
+}
+
+void
+ldns_key_set_origttl(ldns_key *k, uint32_t t)
+{
+	k->_extra.dnssec.orig_ttl = t;
+}
+
+void
+ldns_key_set_inception(ldns_key *k, uint32_t i)
+{
+	k->_extra.dnssec.inception = i;
+}
+
+void
+ldns_key_set_expiration(ldns_key *k, uint32_t e)
+{
+	k->_extra.dnssec.expiration = e;
+}
+
+void
+ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
+{
+	k->_pubkey_owner = r;
+}
+
+void
+ldns_key_set_keytag(ldns_key *k, uint16_t tag)
+{
+	k->_extra.dnssec.keytag = tag;
+}
+
+/* read */
+size_t
+ldns_key_list_key_count(const ldns_key_list *key_list)
+{
+	        return key_list->_key_count;
+}       
+
+ldns_key *
+ldns_key_list_key(const ldns_key_list *key, size_t nr)
+{       
+	if (nr < ldns_key_list_key_count(key)) {
+		return key->_keys[nr];
+	} else {
+		return NULL;
+	}
+}
+
+ldns_signing_algorithm
+ldns_key_algorithm(const ldns_key *k) 
+{
+	return k->_alg;
+}
+
+void
+ldns_key_set_use(ldns_key *k, bool v)
+{
+	if (k) {
+		k->_use = v;
+	}
+}
+
+bool
+ldns_key_use(const ldns_key *k)
+{
+	if (k) {
+		return k->_use;
+	}
+	return false;
+}
+
+#ifdef HAVE_SSL
+#ifndef S_SPLINT_S
+EVP_PKEY *
+ldns_key_evp_key(const ldns_key *k)
+{
+	return k->_key.key;
+}
+
+RSA *
+ldns_key_rsa_key(const ldns_key *k)
+{
+	if (k->_key.key) {
+		return EVP_PKEY_get1_RSA(k->_key.key);
+	} else {
+		return NULL;
+	}
+}
+
+DSA *
+ldns_key_dsa_key(const ldns_key *k)
+{
+	if (k->_key.key) {
+		return EVP_PKEY_get1_DSA(k->_key.key);
+	} else {
+		return NULL;
+	}
+}
+#endif /* splint */
+#endif /* HAVE_SSL */
+
+unsigned char *
+ldns_key_hmac_key(const ldns_key *k)
+{
+	if (k->_key.hmac.key) {
+		return k->_key.hmac.key;
+	} else {
+		return NULL;
+	}
+}
+
+size_t
+ldns_key_hmac_size(const ldns_key *k)
+{
+	if (k->_key.hmac.size) {
+		return k->_key.hmac.size;
+	} else {
+		return 0;
+	}
+}
+
+void *
+ldns_key_external_key(const ldns_key *k)
+{
+	return k->_key.external_key;
+}
+
+uint32_t
+ldns_key_origttl(const ldns_key *k)
+{
+	return k->_extra.dnssec.orig_ttl;
+}
+
+uint16_t
+ldns_key_flags(const ldns_key *k)
+{
+	return k->_extra.dnssec.flags;
+}
+
+uint32_t
+ldns_key_inception(const ldns_key *k)
+{
+	return k->_extra.dnssec.inception;
+}
+
+uint32_t
+ldns_key_expiration(const ldns_key *k)
+{
+	return k->_extra.dnssec.expiration;
+}
+
+uint16_t
+ldns_key_keytag(const ldns_key *k)
+{
+	return k->_extra.dnssec.keytag;
+}
+
+ldns_rdf *
+ldns_key_pubkey_owner(const ldns_key *k)
+{
+	return k->_pubkey_owner;
+}
+
+/* write */
+void
+ldns_key_list_set_use(ldns_key_list *keys, bool v)
+{
+	size_t i;
+
+	for (i = 0; i < ldns_key_list_key_count(keys); i++) {
+		ldns_key_set_use(ldns_key_list_key(keys, i), v);
+	}
+}
+
+void            
+ldns_key_list_set_key_count(ldns_key_list *key, size_t count)
+{
+	        key->_key_count = count;
+}       
+
+bool             
+ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
+{       
+        size_t key_count;
+        ldns_key **keys;
+
+        key_count = ldns_key_list_key_count(key_list);
+
+        /* grow the array */
+        keys = LDNS_XREALLOC(
+                key_list->_keys, ldns_key *, key_count + 1);
+        if (!keys) {
+                return false;
+        }
+
+        /* add the new member */
+        key_list->_keys = keys;
+        key_list->_keys[key_count] = key;
+
+        ldns_key_list_set_key_count(key_list, key_count + 1);
+        return true;
+}
+
+ldns_key *
+ldns_key_list_pop_key(ldns_key_list *key_list)
+{                               
+        size_t key_count;
+        ldns_key** a;
+        ldns_key *pop;
+
+	if (!key_list) {
+		return NULL;
+	}
+        
+        key_count = ldns_key_list_key_count(key_list);
+        if (key_count == 0) {
+                return NULL;
+        }       
+        
+        pop = ldns_key_list_key(key_list, key_count);
+        
+        /* shrink the array */
+        a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1);
+        if(a) {
+                key_list->_keys = a;
+        }
+
+        ldns_key_list_set_key_count(key_list, key_count - 1);
+
+        return pop;
+}       
+
+#ifdef HAVE_SSL
+#ifndef S_SPLINT_S
+/* data pointer must be large enough (LDNS_MAX_KEYLEN) */
+static bool
+ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
+{
+	int i,j;
+	
+	if (!k) {
+		return false;
+	}
+	
+	if (BN_num_bytes(k->e) <= 256) {
+		/* normally only this path is executed (small factors are
+		 * more common 
+		 */
+		data[0] = (unsigned char) BN_num_bytes(k->e);
+		i = BN_bn2bin(k->e, data + 1);  
+		j = BN_bn2bin(k->n, data + i + 1);
+		*size = (uint16_t) i + j;
+	} else if (BN_num_bytes(k->e) <= 65536) {
+		data[0] = 0;
+		/* BN_bn2bin does bigendian, _uint16 also */
+		ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 
+
+		BN_bn2bin(k->e, data + 3); 
+		BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e));
+		*size = (uint16_t) BN_num_bytes(k->n) + 6;
+	} else {
+		return false;
+	}
+	return true;
+}
+
+/* data pointer must be large enough (LDNS_MAX_KEYLEN) */
+static bool
+ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
+{
+	uint8_t T;
+
+	if (!k) {
+		return false;
+	}
+	
+	/* See RFC2536 */
+	*size = (uint16_t)BN_num_bytes(k->p);
+	T = (*size - 64) / 8;
+
+	if (T > 8) {
+#ifdef STDERR_MSGS
+		fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
+		fprintf(stderr, " not implemented\n");
+#endif
+		return false;
+	}
+
+	/* size = 64 + (T * 8); */
+	memset(data, 0, 21 + *size * 3);
+	data[0] = (unsigned char)T;
+	BN_bn2bin(k->q, data + 1 ); 		/* 20 octects */
+	BN_bn2bin(k->p, data + 21 ); 		/* offset octects */
+	BN_bn2bin(k->g, data + 21 + *size * 2 - BN_num_bytes(k->g));
+	BN_bn2bin(k->pub_key,data + 21 + *size * 3 - BN_num_bytes(k->pub_key));
+	*size = 21 + *size * 3;
+	return true;
+}
+
+#ifdef USE_GOST
+static bool
+ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
+{
+	int i;
+	unsigned char* pp = NULL;
+	if(i2d_PUBKEY(k, &pp) != 37 + 64) {
+		/* expect 37 byte(ASN header) and 64 byte(X and Y) */
+		CRYPTO_free(pp);
+		return false;
+	}
+	/* omit ASN header */
+	for(i=0; i<64; i++)
+		data[i] = pp[i+37];
+	CRYPTO_free(pp);
+	*size = 64;
+	return true;
+}
+#endif /* USE_GOST */
+#endif /* splint */
+#endif /* HAVE_SSL */
+
+ldns_rr *
+ldns_key2rr(const ldns_key *k)
+{
+	/* this function will convert a the keydata contained in
+	 * rsa/dsa pointers to a DNSKEY rr. It will fill in as
+	 * much as it can, but it does not know about key-flags
+	 * for instance
+	 */
+	ldns_rr *pubkey;
+	ldns_rdf *keybin;
+	unsigned char *bin = NULL;
+	uint16_t size = 0;
+#ifdef HAVE_SSL
+	RSA *rsa = NULL;
+	DSA *dsa = NULL;
+#endif /* HAVE_SSL */
+#ifdef USE_ECDSA
+        EC_KEY* ec;
+#endif
+	int internal_data = 0;
+
+	if (!k) {
+		return NULL;
+	}
+	pubkey = ldns_rr_new();
+
+	switch (ldns_key_algorithm(k)) {
+	case LDNS_SIGN_HMACMD5:
+	case LDNS_SIGN_HMACSHA1:
+	case LDNS_SIGN_HMACSHA256:
+		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY);
+        	break;
+	default:
+		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY);
+		break;
+        }
+	/* zero-th rdf - flags */
+	ldns_rr_push_rdf(pubkey,
+			ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
+				ldns_key_flags(k)));
+	/* first - proto */
+	ldns_rr_push_rdf(pubkey,
+			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO));
+
+	if (ldns_key_pubkey_owner(k)) {
+		ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k)));
+	}
+
+	/* third - da algorithm */
+	switch(ldns_key_algorithm(k)) {
+		case LDNS_SIGN_RSAMD5:
+		case LDNS_SIGN_RSASHA1:
+		case LDNS_SIGN_RSASHA1_NSEC3:
+		case LDNS_SIGN_RSASHA256:
+		case LDNS_SIGN_RSASHA512:
+			ldns_rr_push_rdf(pubkey,
+						  ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
+#ifdef HAVE_SSL
+			rsa =  ldns_key_rsa_key(k);
+			if (rsa) {
+				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
+				if (!bin) {
+                                        ldns_rr_free(pubkey);
+					return NULL;
+				}
+				if (!ldns_key_rsa2bin(bin, rsa, &size)) {
+		                        LDNS_FREE(bin);
+                                        ldns_rr_free(pubkey);
+					return NULL;
+				}
+				RSA_free(rsa);
+				internal_data = 1;
+			}
+#endif
+			size++;
+			break;
+		case LDNS_SIGN_DSA:
+			ldns_rr_push_rdf(pubkey,
+					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
+#ifdef HAVE_SSL
+			dsa = ldns_key_dsa_key(k);
+			if (dsa) {
+				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
+				if (!bin) {
+                                        ldns_rr_free(pubkey);
+					return NULL;
+				}
+				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
+		                        LDNS_FREE(bin);
+                                        ldns_rr_free(pubkey);
+					return NULL;
+				}
+				DSA_free(dsa);
+				internal_data = 1;
+			}
+#endif /* HAVE_SSL */
+			break;
+		case LDNS_SIGN_DSA_NSEC3:
+			ldns_rr_push_rdf(pubkey,
+					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3));
+#ifdef HAVE_SSL
+			dsa = ldns_key_dsa_key(k);
+			if (dsa) {
+				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
+				if (!bin) {
+                                        ldns_rr_free(pubkey);
+					return NULL;
+				}
+				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
+		                        LDNS_FREE(bin);
+                                        ldns_rr_free(pubkey);
+					return NULL;
+				}
+				DSA_free(dsa);
+				internal_data = 1;
+			}
+#endif /* HAVE_SSL */
+			break;
+		case LDNS_SIGN_ECC_GOST:
+			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
+				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
+#if defined(HAVE_SSL) && defined(USE_GOST)
+			bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
+			if (!bin) {
+                                ldns_rr_free(pubkey);
+				return NULL;
+                        }
+#ifndef S_SPLINT_S
+			if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
+		                LDNS_FREE(bin);
+                                ldns_rr_free(pubkey);
+				return NULL;
+			}
+#endif /* splint */
+			internal_data = 1;
+#else
+                        ldns_rr_free(pubkey);
+			return NULL;
+#endif /* HAVE_SSL and USE_GOST */
+			break;
+                case LDNS_SIGN_ECDSAP256SHA256:
+                case LDNS_SIGN_ECDSAP384SHA384:
+#ifdef USE_ECDSA
+			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
+				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
+                        bin = NULL;
+#ifndef S_SPLINT_S
+                        ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
+#endif
+                        EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
+                        size = (uint16_t)i2o_ECPublicKey(ec, NULL);
+                        if(!i2o_ECPublicKey(ec, &bin)) {
+                                EC_KEY_free(ec);
+                                ldns_rr_free(pubkey);
+                                return NULL;
+                        }
+			if(size > 1) {
+				/* move back one byte to shave off the 0x02
+				 * 'uncompressed' indicator that openssl made
+				 * Actually its 0x04 (from implementation).
+				 */
+				assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
+				size -= 1;
+				memmove(bin, bin+1, size);
+			}
+                        /* down the reference count for ec, its still assigned
+                         * to the pkey */
+                        EC_KEY_free(ec);
+			internal_data = 1;
+#else
+                        ldns_rr_free(pubkey);
+			return NULL;
+#endif /* ECDSA */
+                        break;
+		case LDNS_SIGN_HMACMD5:
+		case LDNS_SIGN_HMACSHA1:
+		case LDNS_SIGN_HMACSHA256:
+			bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
+			if (!bin) {
+                                ldns_rr_free(pubkey);
+				return NULL;
+			}
+			ldns_rr_push_rdf(pubkey,
+			                 ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
+			                 ldns_key_algorithm(k)));
+			size = ldns_key_hmac_size(k);
+			memcpy(bin, ldns_key_hmac_key(k), size);
+			internal_data = 1;
+			break;
+	}
+	/* fourth the key bin material */
+	if (internal_data) {
+		keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin);
+		LDNS_FREE(bin);
+		ldns_rr_push_rdf(pubkey, keybin);
+	}
+	return pubkey;
+}
+
+void
+ldns_key_free(ldns_key *key)
+{
+	LDNS_FREE(key);
+}
+
+void
+ldns_key_deep_free(ldns_key *key)
+{
+	unsigned char* hmac;
+	if (ldns_key_pubkey_owner(key)) {
+		ldns_rdf_deep_free(ldns_key_pubkey_owner(key));
+	}
+#ifdef HAVE_SSL
+	if (ldns_key_evp_key(key)) {
+		EVP_PKEY_free(ldns_key_evp_key(key));
+	}
+#endif /* HAVE_SSL */
+	if (ldns_key_hmac_key(key)) {
+		hmac = ldns_key_hmac_key(key);
+		LDNS_FREE(hmac);
+	}
+	LDNS_FREE(key);
+}
+
+void
+ldns_key_list_free(ldns_key_list *key_list)
+{
+	size_t i;
+	for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
+		ldns_key_deep_free(ldns_key_list_key(key_list, i));
+	}
+	LDNS_FREE(key_list->_keys);
+	LDNS_FREE(key_list);
+}
+
+ldns_rr *
+ldns_read_anchor_file(const char *filename)
+{
+	FILE *fp;
+	/*char line[LDNS_MAX_PACKETLEN];*/
+	char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN);
+	int c;
+	size_t i = 0;
+	ldns_rr *r;
+	ldns_status status;
+        if(!line) {
+                return NULL;
+        }
+
+	fp = fopen(filename, "r");
+	if (!fp) {
+#ifdef STDERR_MSGS
+		fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
+#endif
+		LDNS_FREE(line);
+		return NULL;
+	}
+	
+	while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) {
+		line[i] = c;
+		i++;
+	}
+	line[i] = '\0';
+	
+	fclose(fp);
+	
+	if (i <= 0) {
+#ifdef STDERR_MSGS
+		fprintf(stderr, "nothing read from %s", filename);
+#endif
+		LDNS_FREE(line);
+		return NULL;
+	} else {
+		status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
+		if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) {
+			LDNS_FREE(line);
+			return r;
+		} else {
+#ifdef STDERR_MSGS
+			fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
+#endif
+			LDNS_FREE(line);
+			return NULL;
+		}
+	}
+}
+
+char *
+ldns_key_get_file_base_name(ldns_key *key)
+{
+	ldns_buffer *buffer;
+	char *file_base_name;
+	
+	buffer = ldns_buffer_new(255);
+	ldns_buffer_printf(buffer, "K");
+	(void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key));
+	ldns_buffer_printf(buffer,
+	                   "+%03u+%05u",
+			   ldns_key_algorithm(key),
+			   ldns_key_keytag(key));
+	file_base_name = ldns_buffer_export(buffer);
+	ldns_buffer_free(buffer);
+	return file_base_name;
+}
+
+int ldns_key_algo_supported(int algo)
+{
+	ldns_lookup_table *lt = ldns_signing_algorithms;
+	while(lt->name) {
+		if(lt->id == algo)
+			return 1;
+		lt++;
+	}
+	return 0;
+}
+
+ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name)
+{
+        /* list of (signing algorithm id, alias_name) */
+        ldns_lookup_table aliases[] = {
+                /* from bind dnssec-keygen */
+                {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
+                {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
+                {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
+                /* old ldns usage, now RFC names */
+                {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
+                {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
+#ifdef USE_GOST
+                {LDNS_SIGN_ECC_GOST, "GOST"},
+#endif
+                /* compat with possible output */
+                {LDNS_DH, "DH"},
+                {LDNS_ECC, "ECC"},
+                {LDNS_INDIRECT, "INDIRECT"},
+                {LDNS_PRIVATEDNS, "PRIVATEDNS"},
+                {LDNS_PRIVATEOID, "PRIVATEOID"},
+                {0, NULL}};
+        ldns_lookup_table* lt = ldns_signing_algorithms;
+	ldns_signing_algorithm a;
+	char *endptr;
+
+        while(lt->name) {
+                if(strcasecmp(lt->name, name) == 0)
+                        return lt->id;
+                lt++;
+        }
+        lt = aliases;
+        while(lt->name) {
+                if(strcasecmp(lt->name, name) == 0)
+                        return lt->id;
+                lt++;
+        }
+	a = strtol(name, &endptr, 10);
+	if (*name && !*endptr)
+		return a;
+
+        return 0;
+}
diff --git a/ldns/src/net.c b/ldns/src/net.c
new file mode 100644
index 0000000..b8a5385
--- /dev/null
+++ b/ldns/src/net.c
@@ -0,0 +1,1002 @@
+/*
+ * net.c
+ *
+ * Network implementation
+ * All network related functions are grouped here
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <sys/time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+ldns_status
+ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
+{
+	ldns_buffer *qb;
+	ldns_status result;
+	ldns_rdf *tsig_mac = NULL;
+
+	qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
+
+	if (query_pkt && ldns_pkt_tsig(query_pkt)) {
+		tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
+	}
+
+	if (!query_pkt ||
+	    ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
+		result = LDNS_STATUS_ERR;
+	} else {
+        	result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
+	}
+
+	ldns_buffer_free(qb);
+
+	return result;
+}
+
+/* code from rdata.c */
+static struct sockaddr_storage *
+ldns_rdf2native_sockaddr_storage_port(
+		const ldns_rdf *rd, uint16_t port, size_t *size)
+{
+        struct sockaddr_storage *data;
+        struct sockaddr_in  *data_in;
+        struct sockaddr_in6 *data_in6;
+
+        data = LDNS_MALLOC(struct sockaddr_storage);
+        if (!data) {
+                return NULL;
+        }
+	/* zero the structure for portability */
+	memset(data, 0, sizeof(struct sockaddr_storage));
+
+        switch(ldns_rdf_get_type(rd)) {
+                case LDNS_RDF_TYPE_A:
+#ifndef S_SPLINT_S
+                        data->ss_family = AF_INET;
+#endif
+                        data_in = (struct sockaddr_in*) data;
+                        data_in->sin_port = (in_port_t)htons(port);
+                        memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
+                        *size = sizeof(struct sockaddr_in);
+                        return data;
+                case LDNS_RDF_TYPE_AAAA:
+#ifndef S_SPLINT_S
+                        data->ss_family = AF_INET6;
+#endif
+                        data_in6 = (struct sockaddr_in6*) data;
+                        data_in6->sin6_port = (in_port_t)htons(port);
+                        memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
+                        *size = sizeof(struct sockaddr_in6);
+                        return data;
+                default:
+                        LDNS_FREE(data);
+                        return NULL;
+        }
+}
+
+struct sockaddr_storage *
+ldns_rdf2native_sockaddr_storage(
+		const ldns_rdf *rd, uint16_t port, size_t *size)
+{
+	return ldns_rdf2native_sockaddr_storage_port(
+			rd, (port == 0 ? (uint16_t)LDNS_PORT : port), size);
+}
+
+/** best effort to set nonblocking */
+static void
+ldns_sock_nonblock(int sockfd)
+{
+#ifdef HAVE_FCNTL
+	int flag;
+	if((flag = fcntl(sockfd, F_GETFL)) != -1) {
+		flag |= O_NONBLOCK;
+		if(fcntl(sockfd, F_SETFL, flag) == -1) {
+			/* ignore error, continue blockingly */
+		}
+	}
+#elif defined(HAVE_IOCTLSOCKET)
+	unsigned long on = 1;
+	if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
+		/* ignore error, continue blockingly */
+	}
+#endif
+}
+
+/** best effort to set blocking */
+static void
+ldns_sock_block(int sockfd)
+{
+#ifdef HAVE_FCNTL
+	int flag;
+	if((flag = fcntl(sockfd, F_GETFL)) != -1) {
+		flag &= ~O_NONBLOCK;
+		if(fcntl(sockfd, F_SETFL, flag) == -1) {
+			/* ignore error, continue */
+		}
+	}
+#elif defined(HAVE_IOCTLSOCKET)
+	unsigned long off = 0;
+	if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
+		/* ignore error, continue */
+	}
+#endif
+}
+
+/** wait for a socket to become ready */
+static int
+ldns_sock_wait(int sockfd, struct timeval timeout, int write)
+{
+	int ret;
+#ifndef S_SPLINT_S
+	fd_set fds;
+	FD_ZERO(&fds);
+	FD_SET(FD_SET_T sockfd, &fds);
+	if(write)
+		ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
+	else
+		ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
+#endif
+	if(ret == 0)
+		/* timeout expired */
+		return 0;
+	else if(ret == -1)
+		/* error */
+		return 0;
+	return 1;
+}
+
+
+static int
+ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen, 
+	       	const struct sockaddr_storage *from, socklen_t fromlen,
+		struct timeval timeout)
+{
+	int sockfd;
+
+#ifndef S_SPLINT_S
+	if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM, 
+					IPPROTO_TCP)) == -1) {
+		return 0;
+	}
+#endif
+	if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
+		return 0;
+	}
+
+	/* perform nonblocking connect, to be able to wait with select() */
+	ldns_sock_nonblock(sockfd);
+	if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) {
+#ifndef USE_WINSOCK
+#ifdef EINPROGRESS
+		if(errno != EINPROGRESS) {
+#else
+		if(1) {
+#endif
+			close(sockfd);
+			return 0;
+		}
+#else /* USE_WINSOCK */
+		if(WSAGetLastError() != WSAEINPROGRESS &&
+			WSAGetLastError() != WSAEWOULDBLOCK) {
+			closesocket(sockfd);
+			return 0;
+		}
+#endif
+		/* error was only telling us that it would block */
+	}
+
+	/* wait(write) until connected or error */
+	while(1) {
+		int error = 0;
+		socklen_t len = (socklen_t)sizeof(error);
+
+		if(!ldns_sock_wait(sockfd, timeout, 1)) {
+#ifndef USE_WINSOCK
+			close(sockfd);
+#else
+			closesocket(sockfd);
+#endif
+			return 0;
+		}
+
+		/* check if there is a pending error for nonblocking connect */
+		if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error,
+			&len) < 0) {
+#ifndef USE_WINSOCK
+			error = errno; /* on solaris errno is error */
+#else
+			error = WSAGetLastError();
+#endif
+		}
+#ifndef USE_WINSOCK
+#if defined(EINPROGRESS) && defined(EWOULDBLOCK)
+		if(error == EINPROGRESS || error == EWOULDBLOCK)
+			continue; /* try again */
+#endif
+		else if(error != 0) {
+			close(sockfd);
+			/* error in errno for our user */
+			errno = error;
+			return 0;
+		}
+#else /* USE_WINSOCK */
+		if(error == WSAEINPROGRESS)
+			continue;
+		else if(error == WSAEWOULDBLOCK)
+			continue;
+		else if(error != 0) {
+			closesocket(sockfd);
+			errno = error;
+			return 0;
+		}
+#endif /* USE_WINSOCK */
+		/* connected */
+		break;
+	}
+
+	/* set the socket blocking again */
+	ldns_sock_block(sockfd);
+
+	return sockfd;
+}
+
+int
+ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, 
+		struct timeval timeout)
+{
+	return ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
+}
+
+static int
+ldns_tcp_bgsend_from(ldns_buffer *qbin,
+		const struct sockaddr_storage *to, socklen_t tolen, 
+	       	const struct sockaddr_storage *from, socklen_t fromlen,
+		struct timeval timeout)
+{
+	int sockfd;
+	
+	sockfd = ldns_tcp_connect_from(to, tolen, from, fromlen, timeout);
+	
+	if (sockfd == 0) {
+		return 0;
+	}
+	
+	if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
+#ifndef USE_WINSOCK
+		close(sockfd);
+#else
+		closesocket(sockfd);
+#endif
+		return 0;
+	}
+	
+	return sockfd;
+}
+
+int
+ldns_tcp_bgsend(ldns_buffer *qbin,
+		const struct sockaddr_storage *to, socklen_t tolen, 
+		struct timeval timeout)
+{
+	return ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
+}
+
+
+/* keep in mind that in DNS tcp messages the first 2 bytes signal the
+ * amount data to expect
+ */
+static ldns_status
+ldns_tcp_send_from(uint8_t **result,  ldns_buffer *qbin,
+	       	const struct sockaddr_storage *to, socklen_t tolen,
+	       	const struct sockaddr_storage *from, socklen_t fromlen,
+		struct timeval timeout, size_t *answer_size)
+{
+	int sockfd;
+	uint8_t *answer;
+	
+	sockfd = ldns_tcp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
+	
+	if (sockfd == 0) {
+		return LDNS_STATUS_ERR;
+	}
+
+	answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
+#ifndef USE_WINSOCK
+	close(sockfd);
+#else
+	closesocket(sockfd);
+#endif
+
+	if (*answer_size == 0) {
+		/* oops */
+		return LDNS_STATUS_NETWORK_ERR;
+	}
+
+	/* resize accordingly */
+	*result = LDNS_XREALLOC(answer, uint8_t, (size_t)*answer_size);
+        if(!*result) {
+                LDNS_FREE(answer);
+                return LDNS_STATUS_MEM_ERR;
+        }
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_tcp_send(uint8_t **result,  ldns_buffer *qbin,
+		const struct sockaddr_storage *to, socklen_t tolen,
+		struct timeval timeout, size_t *answer_size)
+{
+	return ldns_tcp_send_from(result, qbin,
+			to, tolen, NULL, 0, timeout, answer_size);
+}
+
+int
+ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
+{
+	int sockfd;
+
+#ifndef S_SPLINT_S
+	if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM, 
+					IPPROTO_UDP)) 
+			== -1) {
+                return 0;
+        }
+#endif
+	return sockfd;
+}
+
+static int
+ldns_udp_bgsend_from(ldns_buffer *qbin,
+		const struct sockaddr_storage *to  , socklen_t tolen, 
+		const struct sockaddr_storage *from, socklen_t fromlen, 
+		struct timeval timeout)
+{
+	int sockfd;
+
+	sockfd = ldns_udp_connect(to, timeout);
+
+	if (sockfd == 0) {
+		return 0;
+	}
+
+	if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
+		return 0;
+	}
+
+	if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
+#ifndef USE_WINSOCK
+		close(sockfd);
+#else
+		closesocket(sockfd);
+#endif
+		return 0;
+	}
+	return sockfd;
+}
+
+int
+ldns_udp_bgsend(ldns_buffer *qbin,
+		const struct sockaddr_storage *to  , socklen_t tolen, 
+		struct timeval timeout)
+{
+	return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
+}
+
+static ldns_status
+ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
+		const struct sockaddr_storage *to  , socklen_t tolen,
+		const struct sockaddr_storage *from, socklen_t fromlen,
+		struct timeval timeout, size_t *answer_size)
+{
+	int sockfd;
+	uint8_t *answer;
+
+	sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
+
+	if (sockfd == 0) {
+		return LDNS_STATUS_SOCKET_ERROR;
+	}
+
+	/* wait for an response*/
+	if(!ldns_sock_wait(sockfd, timeout, 0)) {
+#ifndef USE_WINSOCK
+		close(sockfd);
+#else
+                closesocket(sockfd);
+#endif
+		return LDNS_STATUS_NETWORK_ERR;
+	}
+
+        /* set to nonblocking, so if the checksum is bad, it becomes
+         * an EGAIN error and the ldns_udp_send function does not block,
+         * but returns a 'NETWORK_ERROR' much like a timeout. */
+        ldns_sock_nonblock(sockfd);
+
+	answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
+#ifndef USE_WINSOCK
+	close(sockfd);
+#else
+        closesocket(sockfd);
+#endif
+
+	if (*answer_size == 0) {
+		/* oops */
+		return LDNS_STATUS_NETWORK_ERR;
+	}
+
+	*result = answer;
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_udp_send(uint8_t **result, ldns_buffer *qbin,
+		const struct sockaddr_storage *to  , socklen_t tolen,
+		struct timeval timeout, size_t *answer_size)
+{
+	return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
+			timeout, answer_size);
+}
+
+ldns_status
+ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
+{
+	uint8_t i;
+
+	struct sockaddr_storage *src = NULL;
+	size_t src_len;
+	struct sockaddr_storage *ns;
+	size_t ns_len;
+	struct timeval tv_s;
+	struct timeval tv_e;
+
+	ldns_rdf **ns_array;
+	size_t *rtt;
+	ldns_pkt *reply;
+	bool all_servers_rtt_inf;
+	uint8_t retries;
+
+	uint8_t *reply_bytes = NULL;
+	size_t reply_size = 0;
+	ldns_status status, send_status;
+
+	assert(r != NULL);
+
+	status = LDNS_STATUS_OK;
+	rtt = ldns_resolver_rtt(r);
+	ns_array = ldns_resolver_nameservers(r);
+	reply = NULL; 
+	ns_len = 0;
+
+	all_servers_rtt_inf = true;
+
+	if (ldns_resolver_random(r)) {
+		ldns_resolver_nameservers_randomize(r);
+	}
+
+	if(ldns_resolver_source(r)) {
+		src = ldns_rdf2native_sockaddr_storage_port(
+				ldns_resolver_source(r), 0, &src_len);
+	}
+
+	/* loop through all defined nameservers */
+	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
+		if (rtt[i] == LDNS_RESOLV_RTT_INF) {
+			/* not reachable nameserver! */
+			continue;
+		}
+
+		/* maybe verbosity setting?
+		printf("Sending to ");
+		ldns_rdf_print(stdout, ns_array[i]);
+		printf("\n");
+		*/
+		ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
+				ldns_resolver_port(r), &ns_len);
+
+
+#ifndef S_SPLINT_S
+		if ((ns->ss_family == AF_INET) &&
+				(ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
+			/* not reachable */
+			LDNS_FREE(ns);
+			continue;
+		}
+
+		if ((ns->ss_family == AF_INET6) &&
+				 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
+			/* not reachable */
+			LDNS_FREE(ns);
+			continue;
+		}
+#endif
+
+		all_servers_rtt_inf = false;
+
+		gettimeofday(&tv_s, NULL);
+
+		send_status = LDNS_STATUS_ERR;
+
+		/* reply_bytes implicitly handles our error */
+		if (ldns_resolver_usevc(r)) {
+			for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
+				send_status = 
+					ldns_tcp_send_from(&reply_bytes, qb, 
+						ns, (socklen_t)ns_len,
+						src, (socklen_t)src_len,
+						ldns_resolver_timeout(r),
+						&reply_size);
+				if (send_status == LDNS_STATUS_OK) {
+					break;
+				}
+			}
+		} else {
+			for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
+				/* ldns_rdf_print(stdout, ns_array[i]); */
+				send_status = 
+					ldns_udp_send_from(&reply_bytes, qb,
+						ns,  (socklen_t)ns_len,
+						src, (socklen_t)src_len,
+						ldns_resolver_timeout(r),
+						&reply_size);
+				if (send_status == LDNS_STATUS_OK) {
+					break;
+				}
+			}
+		}
+
+		if (send_status != LDNS_STATUS_OK) {
+			ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
+			status = send_status;
+		}
+		
+		/* obey the fail directive */
+		if (!reply_bytes) {
+			/* the current nameserver seems to have a problem, blacklist it */
+			if (ldns_resolver_fail(r)) {
+				LDNS_FREE(ns);
+				return LDNS_STATUS_ERR;
+			} else {
+				LDNS_FREE(ns);
+				continue;
+			}
+		} 
+		
+		status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
+		if (status != LDNS_STATUS_OK) {
+			LDNS_FREE(reply_bytes);
+			LDNS_FREE(ns);
+			return status;
+		}
+		
+		LDNS_FREE(ns);
+		gettimeofday(&tv_e, NULL);
+
+		if (reply) {
+			ldns_pkt_set_querytime(reply, (uint32_t)
+				((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
+				(tv_e.tv_usec - tv_s.tv_usec) / 1000);
+			ldns_pkt_set_answerfrom(reply,
+					ldns_rdf_clone(ns_array[i]));
+			ldns_pkt_set_timestamp(reply, tv_s);
+			ldns_pkt_set_size(reply, reply_size);
+			break;
+		} else {
+			if (ldns_resolver_fail(r)) {
+				/* if fail is set bail out, after the first
+				 * one */
+				break;
+			}
+		}
+
+		/* wait retrans seconds... */
+		sleep((unsigned int) ldns_resolver_retrans(r));
+	}
+
+	if(src) {
+		LDNS_FREE(src);
+	}
+	if (all_servers_rtt_inf) {
+		LDNS_FREE(reply_bytes);
+		return LDNS_STATUS_RES_NO_NS;
+	}
+#ifdef HAVE_SSL
+	if (tsig_mac && reply && reply_bytes) {
+		if (!ldns_pkt_tsig_verify(reply,
+		                          reply_bytes,
+					  reply_size,
+		                          ldns_resolver_tsig_keyname(r),
+		                          ldns_resolver_tsig_keydata(r), tsig_mac)) {
+			status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
+		}
+	}
+#else
+	(void)tsig_mac;
+#endif /* HAVE_SSL */
+
+	LDNS_FREE(reply_bytes);
+	if (result) {
+		*result = reply;
+	}
+
+	return status;
+}
+
+ssize_t
+ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, 
+                    const struct sockaddr_storage *to, socklen_t tolen)
+{
+	uint8_t *sendbuf;
+	ssize_t bytes;
+
+	/* add length of packet */
+	sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
+	if(!sendbuf) return 0;
+	ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
+	memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
+
+	bytes = sendto(sockfd, (void*)sendbuf,
+			ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
+
+        LDNS_FREE(sendbuf);
+
+	if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
+		return 0;
+	}
+	return bytes;
+}
+
+/* don't wait for an answer */
+ssize_t
+ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, 
+		socklen_t tolen)
+{
+	ssize_t bytes;
+
+	bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
+			ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
+
+	if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
+		return 0;
+	}
+	if ((size_t) bytes != ldns_buffer_position(qbin)) {
+		return 0;
+	}
+	return bytes;
+}
+
+uint8_t *
+ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
+		socklen_t *fromlen)
+{
+	uint8_t *wire, *wireout;
+	ssize_t wire_size;
+
+	wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
+	if (!wire) {
+		*size = 0;
+		return NULL;
+	}
+
+	wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0, 
+			(struct sockaddr *)from, fromlen);
+
+	/* recvfrom can also return 0 */
+	if (wire_size == -1 || wire_size == 0) {
+		*size = 0;
+		LDNS_FREE(wire);
+		return NULL;
+	}
+
+	*size = (size_t)wire_size;
+	wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
+	if(!wireout) LDNS_FREE(wire);
+
+	return wireout;
+}
+
+uint8_t *
+ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
+{
+	uint8_t *wire;
+	uint16_t wire_size;
+	ssize_t bytes = 0, rc = 0;
+
+	wire = LDNS_XMALLOC(uint8_t, 2);
+	if (!wire) {
+		*size = 0;
+		return NULL;
+	}
+	
+	while (bytes < 2) {
+		if(!ldns_sock_wait(sockfd, timeout, 0)) {
+			*size = 0;
+			LDNS_FREE(wire);
+			return NULL;
+		}
+		rc = recv(sockfd, (void*) (wire + bytes), 
+				(size_t) (2 - bytes), 0);
+		if (rc == -1 || rc == 0) {
+			*size = 0;
+			LDNS_FREE(wire);
+			return NULL;
+		}
+                bytes += rc;
+	}
+
+	wire_size = ldns_read_uint16(wire);
+	
+	LDNS_FREE(wire);
+	wire = LDNS_XMALLOC(uint8_t, wire_size);
+	if (!wire) {
+		*size = 0;
+		return NULL;
+	}
+	bytes = 0;
+
+	while (bytes < (ssize_t) wire_size) {
+		if(!ldns_sock_wait(sockfd, timeout, 0)) {
+			*size = 0;
+			LDNS_FREE(wire);
+			return NULL;
+		}
+		rc = recv(sockfd, (void*) (wire + bytes), 
+				(size_t) (wire_size - bytes), 0);
+		if (rc == -1 || rc == 0) {
+			LDNS_FREE(wire);
+			*size = 0;
+			return NULL;
+		}
+                bytes += rc;
+	}
+	
+	*size = (size_t) bytes;
+	return wire;
+}
+
+uint8_t *
+ldns_tcp_read_wire(int sockfd, size_t *size)
+{
+	uint8_t *wire;
+	uint16_t wire_size;
+	ssize_t bytes = 0, rc = 0;
+
+	wire = LDNS_XMALLOC(uint8_t, 2);
+	if (!wire) {
+		*size = 0;
+		return NULL;
+	}
+	
+	while (bytes < 2) {
+		rc = recv(sockfd, (void*) (wire + bytes), 
+				(size_t) (2 - bytes), 0);
+		if (rc == -1 || rc == 0) {
+			*size = 0;
+			LDNS_FREE(wire);
+			return NULL;
+		}
+                bytes += rc;
+	}
+
+	wire_size = ldns_read_uint16(wire);
+	
+	LDNS_FREE(wire);
+	wire = LDNS_XMALLOC(uint8_t, wire_size);
+	if (!wire) {
+		*size = 0;
+		return NULL;
+	}
+	bytes = 0;
+
+	while (bytes < (ssize_t) wire_size) {
+		rc = recv(sockfd, (void*) (wire + bytes), 
+				(size_t) (wire_size - bytes), 0);
+		if (rc == -1 || rc == 0) {
+			LDNS_FREE(wire);
+			*size = 0;
+			return NULL;
+		}
+                bytes += rc;
+	}
+	
+	*size = (size_t) bytes;
+	return wire;
+}
+
+#ifndef S_SPLINT_S
+ldns_rdf *
+ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
+{
+        ldns_rdf *addr;
+        struct sockaddr_in *data_in;
+        struct sockaddr_in6 *data_in6;
+
+        switch(sock->ss_family) {
+                case AF_INET:
+                        data_in = (struct sockaddr_in*)sock;
+                        if (port) {
+                                *port = ntohs((uint16_t)data_in->sin_port);
+                        }
+                        addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
+                                        LDNS_IP4ADDRLEN, &data_in->sin_addr);
+                        break;
+                case AF_INET6:
+                        data_in6 = (struct sockaddr_in6*)sock;
+                        if (port) {
+                                *port = ntohs((uint16_t)data_in6->sin6_port);
+                        }
+                        addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
+                                        LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
+                        break;
+                default:
+                        if (port) {
+                                *port = 0;
+                        }
+                        return NULL;
+        }
+        return addr;
+}
+#endif
+
+/* code from resolver.c */
+ldns_status
+ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) 
+{
+        ldns_pkt *query;
+        ldns_buffer *query_wire;
+
+        struct sockaddr_storage *src = NULL;
+        size_t src_len = 0;
+        struct sockaddr_storage *ns = NULL;
+        size_t ns_len = 0;
+        size_t ns_i;
+        ldns_status status;
+
+        if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
+                return LDNS_STATUS_ERR;
+        }
+
+        query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
+
+        if (!query) {
+                return LDNS_STATUS_ADDRESS_ERR;
+        }
+	if(ldns_resolver_source(resolver)) {
+		src = ldns_rdf2native_sockaddr_storage_port(
+				ldns_resolver_source(resolver), 0, &src_len);
+	}
+        /* For AXFR, we have to make the connection ourselves */
+        /* try all nameservers (which usually would mean v4 fallback if
+         * @hostname is used */
+        for (ns_i = 0;
+             ns_i < ldns_resolver_nameserver_count(resolver) &&
+             resolver->_socket == 0;
+             ns_i++) {
+		if (ns != NULL) {
+			LDNS_FREE(ns);
+		}
+	        ns = ldns_rdf2native_sockaddr_storage(
+	        	resolver->_nameservers[ns_i],
+			ldns_resolver_port(resolver), &ns_len);
+
+		resolver->_socket = ldns_tcp_connect_from(
+				ns, (socklen_t)ns_len,
+				src, (socklen_t)src_len,
+				ldns_resolver_timeout(resolver));
+	}
+
+	if (resolver->_socket == 0) {
+		ldns_pkt_free(query);
+		LDNS_FREE(ns);
+		return LDNS_STATUS_NETWORK_ERR;
+	}
+
+#ifdef HAVE_SSL
+	if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
+		status = ldns_pkt_tsig_sign(query,
+		                            ldns_resolver_tsig_keyname(resolver),
+		                            ldns_resolver_tsig_keydata(resolver),
+		                            300, ldns_resolver_tsig_algorithm(resolver), NULL);
+		if (status != LDNS_STATUS_OK) {
+			/* to prevent problems on subsequent calls to 
+			 * ldns_axfr_start we have to close the socket here! */
+#ifndef USE_WINSOCK
+			close(resolver->_socket);
+#else
+			closesocket(resolver->_socket);
+#endif
+			resolver->_socket = 0;
+
+			ldns_pkt_free(query);
+			LDNS_FREE(ns);
+
+			return LDNS_STATUS_CRYPTO_TSIG_ERR;
+		}
+	}
+#endif /* HAVE_SSL */
+
+        /* Convert the query to a buffer
+         * Is this necessary?
+         */
+        query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+        if(!query_wire) {
+                ldns_pkt_free(query);
+                LDNS_FREE(ns);
+#ifndef USE_WINSOCK
+		close(resolver->_socket);
+#else
+		closesocket(resolver->_socket);
+#endif
+		resolver->_socket = 0;
+
+                return LDNS_STATUS_MEM_ERR;
+        }
+        status = ldns_pkt2buffer_wire(query_wire, query);
+        if (status != LDNS_STATUS_OK) {
+                ldns_pkt_free(query);
+		ldns_buffer_free(query_wire);
+                LDNS_FREE(ns);
+
+		/* to prevent problems on subsequent calls to ldns_axfr_start
+		 * we have to close the socket here! */
+#ifndef USE_WINSOCK
+		close(resolver->_socket);
+#else
+		closesocket(resolver->_socket);
+#endif
+		resolver->_socket = 0;
+
+                return status;
+        }
+        /* Send the query */
+        if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
+				(socklen_t)ns_len) == 0) {
+                ldns_pkt_free(query);
+                ldns_buffer_free(query_wire);
+                LDNS_FREE(ns);
+
+		/* to prevent problems on subsequent calls to ldns_axfr_start
+		 * we have to close the socket here! */
+
+#ifndef USE_WINSOCK
+		close(resolver->_socket);
+#else
+		closesocket(resolver->_socket);
+#endif
+		resolver->_socket = 0;
+
+                return LDNS_STATUS_NETWORK_ERR;
+        }
+
+        ldns_pkt_free(query);
+        ldns_buffer_free(query_wire);
+        LDNS_FREE(ns);
+
+        /*
+         * The AXFR is done once the second SOA record is sent
+         */
+        resolver->_axfr_soa_count = 0;
+        return LDNS_STATUS_OK;
+}
diff --git a/ldns/src/packet.c b/ldns/src/packet.c
new file mode 100644
index 0000000..62bfd07
--- /dev/null
+++ b/ldns/src/packet.c
@@ -0,0 +1,1159 @@
+/*
+ * packet.c
+ *
+ * dns packet implementation
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <strings.h>
+#include <limits.h>
+
+#ifdef HAVE_SSL
+#include <openssl/rand.h>
+#endif
+
+/* Access functions 
+ * do this as functions to get type checking
+ */
+
+#define LDNS_EDNS_MASK_DO_BIT 0x8000
+
+/* TODO defines for 3600 */
+/* convert to and from numerical flag values */
+ldns_lookup_table ldns_edns_flags[] = {
+	{ 3600, "do"},
+	{ 0, NULL}
+};
+
+/* read */
+uint16_t
+ldns_pkt_id(const ldns_pkt *packet)
+{
+	return packet->_header->_id;
+}
+
+bool
+ldns_pkt_qr(const ldns_pkt *packet)
+{
+	return packet->_header->_qr;
+}
+
+bool
+ldns_pkt_aa(const ldns_pkt *packet)
+{
+	return packet->_header->_aa;
+}
+
+bool
+ldns_pkt_tc(const ldns_pkt *packet)
+{
+	return packet->_header->_tc;
+}
+
+bool
+ldns_pkt_rd(const ldns_pkt *packet)
+{
+	return packet->_header->_rd;
+}
+
+bool
+ldns_pkt_cd(const ldns_pkt *packet)
+{
+	return packet->_header->_cd;
+}
+
+bool
+ldns_pkt_ra(const ldns_pkt *packet)
+{
+	return packet->_header->_ra;
+}
+
+bool
+ldns_pkt_ad(const ldns_pkt *packet)
+{
+	return packet->_header->_ad;
+}
+
+ldns_pkt_opcode
+ldns_pkt_get_opcode(const ldns_pkt *packet)
+{
+	return packet->_header->_opcode;
+}
+
+ldns_pkt_rcode
+ldns_pkt_get_rcode(const ldns_pkt *packet)
+{
+	return packet->_header->_rcode;
+}
+
+uint16_t
+ldns_pkt_qdcount(const ldns_pkt *packet)
+{
+	return packet->_header->_qdcount;
+}
+
+uint16_t
+ldns_pkt_ancount(const ldns_pkt *packet)
+{
+	return packet->_header->_ancount;
+}
+
+uint16_t
+ldns_pkt_nscount(const ldns_pkt *packet)
+{
+	return packet->_header->_nscount;
+}
+
+uint16_t
+ldns_pkt_arcount(const ldns_pkt *packet)
+{
+	return packet->_header->_arcount;
+}
+
+ldns_rr_list *
+ldns_pkt_question(const ldns_pkt *packet)
+{
+	return packet->_question;
+}
+
+ldns_rr_list *
+ldns_pkt_answer(const ldns_pkt *packet)
+{
+	return packet->_answer;
+}
+
+ldns_rr_list *
+ldns_pkt_authority(const ldns_pkt *packet)
+{
+	return packet->_authority;
+}
+
+ldns_rr_list *
+ldns_pkt_additional(const ldns_pkt *packet)
+{
+	return packet->_additional;
+}
+
+/* return ALL section concatenated */
+ldns_rr_list *
+ldns_pkt_all(const ldns_pkt *packet)
+{
+	ldns_rr_list *all, *prev_all;
+
+	all = ldns_rr_list_cat_clone(
+			ldns_pkt_question(packet),
+			ldns_pkt_answer(packet));
+	prev_all = all;
+	all = ldns_rr_list_cat_clone(all,
+			ldns_pkt_authority(packet));
+	ldns_rr_list_deep_free(prev_all);
+	prev_all = all;
+	all = ldns_rr_list_cat_clone(all,
+			ldns_pkt_additional(packet));
+	ldns_rr_list_deep_free(prev_all);
+	return all;
+}
+
+ldns_rr_list *
+ldns_pkt_all_noquestion(const ldns_pkt *packet)
+{
+	ldns_rr_list *all, *all2;
+
+	all = ldns_rr_list_cat_clone(
+			ldns_pkt_answer(packet),
+			ldns_pkt_authority(packet));
+	all2 = ldns_rr_list_cat_clone(all,
+			ldns_pkt_additional(packet));
+	
+	ldns_rr_list_deep_free(all);
+	return all2;
+}
+
+size_t
+ldns_pkt_size(const ldns_pkt *packet)
+{
+	return packet->_size;
+}
+
+uint32_t 
+ldns_pkt_querytime(const ldns_pkt *packet)
+{
+	return packet->_querytime;
+}
+
+ldns_rdf *
+ldns_pkt_answerfrom(const ldns_pkt *packet)
+{
+	return packet->_answerfrom;
+}
+
+struct timeval
+ldns_pkt_timestamp(const ldns_pkt *packet)
+{
+	return packet->timestamp;
+}
+
+uint16_t
+ldns_pkt_edns_udp_size(const ldns_pkt *packet)
+{
+	return packet->_edns_udp_size;
+}
+
+uint8_t
+ldns_pkt_edns_extended_rcode(const ldns_pkt *packet)
+{
+	return packet->_edns_extended_rcode;
+}
+
+uint8_t
+ldns_pkt_edns_version(const ldns_pkt *packet)
+{
+	return packet->_edns_version;
+}
+
+uint16_t
+ldns_pkt_edns_z(const ldns_pkt *packet)
+{
+	return packet->_edns_z;
+}
+
+bool
+ldns_pkt_edns_do(const ldns_pkt *packet)
+{
+	return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT);
+}
+
+void
+ldns_pkt_set_edns_do(ldns_pkt *packet, bool value)
+{
+	if (value) {
+		packet->_edns_z = packet->_edns_z | LDNS_EDNS_MASK_DO_BIT;
+	} else {
+		packet->_edns_z = packet->_edns_z & ~LDNS_EDNS_MASK_DO_BIT;
+	}
+}
+
+ldns_rdf *
+ldns_pkt_edns_data(const ldns_pkt *packet)
+{
+	return packet->_edns_data;
+}
+
+/* return only those rr that share the ownername */
+ldns_rr_list *
+ldns_pkt_rr_list_by_name(ldns_pkt *packet,
+                         ldns_rdf *ownername,
+                         ldns_pkt_section sec)
+{
+	ldns_rr_list *rrs;
+	ldns_rr_list *ret;
+	uint16_t i;
+
+	if (!packet) {
+		return NULL;
+	}
+
+	rrs = ldns_pkt_get_section_clone(packet, sec);
+	ret = NULL;
+
+	for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
+		if (ldns_dname_compare(ldns_rr_owner(
+						ldns_rr_list_rr(rrs, i)), 
+					ownername) == 0) {
+			/* owner names match */
+			if (ret == NULL) {
+				ret = ldns_rr_list_new();
+			}
+			ldns_rr_list_push_rr(ret,
+					     ldns_rr_clone(
+						ldns_rr_list_rr(rrs, i))
+					    );
+		}
+	}
+
+	ldns_rr_list_deep_free(rrs);
+
+	return ret;
+}
+
+/* return only those rr that share a type */
+ldns_rr_list *
+ldns_pkt_rr_list_by_type(const ldns_pkt *packet,
+                         ldns_rr_type type,
+                         ldns_pkt_section sec)
+{
+	ldns_rr_list *rrs;
+	ldns_rr_list *new;
+	uint16_t i;
+
+	if(!packet) {
+		return NULL;
+	}
+	
+	rrs = ldns_pkt_get_section_clone(packet, sec);
+	new = ldns_rr_list_new();
+	
+	for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
+		if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) {
+			/* types match */
+			ldns_rr_list_push_rr(new, 
+			                     ldns_rr_clone(
+			                     	ldns_rr_list_rr(rrs, i))
+					     );
+		}
+	}
+	ldns_rr_list_deep_free(rrs);
+
+	if (ldns_rr_list_rr_count(new) == 0) {
+		ldns_rr_list_free(new);
+		return NULL;
+	} else {
+		return new;
+	}
+}
+
+/* return only those rrs that share name and type */
+ldns_rr_list *
+ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet,
+                                  const ldns_rdf *ownername,
+                                  ldns_rr_type type,
+                                  ldns_pkt_section sec)
+{
+	ldns_rr_list *rrs;
+	ldns_rr_list *new;
+	ldns_rr_list *ret;
+	uint16_t i;
+
+	if(!packet) {
+		return NULL;
+	}
+	
+	rrs = ldns_pkt_get_section_clone(packet, sec);
+	new = ldns_rr_list_new();
+	ret = NULL;
+
+	for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
+		if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) &&
+		    ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)),
+		                     ownername
+		                    ) == 0
+		   ) {
+			/* types match */
+			ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i)));
+			ret = new;
+		}
+	}
+	ldns_rr_list_deep_free(rrs);
+	if (!ret) {
+		ldns_rr_list_free(new);
+	}
+	return ret;
+}
+
+bool
+ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
+{
+	bool result = false;
+
+	switch (sec) {
+	case LDNS_SECTION_QUESTION:
+		return ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
+	case LDNS_SECTION_ANSWER:
+		return ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr);
+	case LDNS_SECTION_AUTHORITY:
+		return ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr);
+	case LDNS_SECTION_ADDITIONAL:
+		return ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
+	case LDNS_SECTION_ANY:
+		result = ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
+	case LDNS_SECTION_ANY_NOQUESTION:
+		result = result
+		    || ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr)
+		    || ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr)
+		    || ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
+	}
+
+	return result;
+}
+
+uint16_t
+ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s)
+{
+	switch(s) {
+	case LDNS_SECTION_QUESTION:
+		return ldns_pkt_qdcount(packet);
+	case LDNS_SECTION_ANSWER:
+		return ldns_pkt_ancount(packet);
+	case LDNS_SECTION_AUTHORITY:
+		return ldns_pkt_nscount(packet);
+	case LDNS_SECTION_ADDITIONAL:
+		return ldns_pkt_arcount(packet);
+	case LDNS_SECTION_ANY:
+		return ldns_pkt_qdcount(packet) +
+			ldns_pkt_ancount(packet) +
+			ldns_pkt_nscount(packet) +
+			ldns_pkt_arcount(packet);
+	case LDNS_SECTION_ANY_NOQUESTION:
+		return ldns_pkt_ancount(packet) +
+			ldns_pkt_nscount(packet) +
+			ldns_pkt_arcount(packet);
+	default:
+		return 0;
+	}
+}
+
+bool
+ldns_pkt_empty(ldns_pkt *p)
+{
+	if (!p) {
+		return true; /* NULL is empty? */
+	}
+	if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) {
+		return false;
+	} else {
+		return true;
+    }
+}
+
+
+ldns_rr_list *
+ldns_pkt_get_section_clone(const ldns_pkt *packet, ldns_pkt_section s)
+{
+	switch(s) {
+	case LDNS_SECTION_QUESTION:
+		return ldns_rr_list_clone(ldns_pkt_question(packet));
+	case LDNS_SECTION_ANSWER:
+		return ldns_rr_list_clone(ldns_pkt_answer(packet));
+	case LDNS_SECTION_AUTHORITY:
+		return ldns_rr_list_clone(ldns_pkt_authority(packet));
+	case LDNS_SECTION_ADDITIONAL:
+		return ldns_rr_list_clone(ldns_pkt_additional(packet));
+	case LDNS_SECTION_ANY:
+		/* these are already clones */
+		return ldns_pkt_all(packet);
+	case LDNS_SECTION_ANY_NOQUESTION:
+		return ldns_pkt_all_noquestion(packet);
+	default:
+		return NULL;
+	}
+}
+
+ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) {
+	return pkt->_tsig_rr;
+}
+
+/* write */
+void
+ldns_pkt_set_id(ldns_pkt *packet, uint16_t id)
+{
+	packet->_header->_id = id;
+}
+
+void
+ldns_pkt_set_random_id(ldns_pkt *packet)
+{
+	uint16_t rid = ldns_get_random();
+	ldns_pkt_set_id(packet, rid);
+}
+
+
+void
+ldns_pkt_set_qr(ldns_pkt *packet, bool qr)
+{
+	packet->_header->_qr = qr;
+}
+
+void
+ldns_pkt_set_aa(ldns_pkt *packet, bool aa)
+{
+	packet->_header->_aa = aa;
+}
+
+void
+ldns_pkt_set_tc(ldns_pkt *packet, bool tc)
+{
+	packet->_header->_tc = tc;
+}
+
+void
+ldns_pkt_set_rd(ldns_pkt *packet, bool rd)
+{
+	packet->_header->_rd = rd;
+}
+
+void
+ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr)
+{
+	p->_additional = rr;
+}
+
+void
+ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr)
+{
+	p->_question = rr;
+}
+
+void
+ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr)
+{
+	p->_answer = rr;
+}
+
+void
+ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr)
+{
+	p->_authority = rr;
+}
+
+void
+ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
+{
+	packet->_header->_cd = cd;
+}
+
+void
+ldns_pkt_set_ra(ldns_pkt *packet, bool ra)
+{
+	packet->_header->_ra = ra;
+}
+
+void
+ldns_pkt_set_ad(ldns_pkt *packet, bool ad)
+{
+	packet->_header->_ad = ad;
+}
+
+void
+ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode)
+{
+	packet->_header->_opcode = opcode;
+}
+
+void
+ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode)
+{
+	packet->_header->_rcode = rcode;
+}
+
+void
+ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount)
+{
+	packet->_header->_qdcount = qdcount;
+}
+
+void
+ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount)
+{
+	packet->_header->_ancount = ancount;
+}
+
+void
+ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount)
+{
+	packet->_header->_nscount = nscount;
+}
+
+void
+ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount)
+{
+	packet->_header->_arcount = arcount;
+}
+
+void
+ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 
+{
+	packet->_querytime = time;
+}
+
+void
+ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
+{
+	packet->_answerfrom = answerfrom;
+}
+
+void
+ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
+{
+	packet->timestamp.tv_sec = timeval.tv_sec;
+	packet->timestamp.tv_usec = timeval.tv_usec;
+}
+
+void
+ldns_pkt_set_size(ldns_pkt *packet, size_t s)
+{
+	packet->_size = s;
+}
+
+void
+ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s)
+{
+	packet->_edns_udp_size = s;
+}
+
+void
+ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c)
+{
+	packet->_edns_extended_rcode = c;
+}
+
+void
+ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v)
+{
+	packet->_edns_version = v;
+}
+
+void
+ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z)
+{
+	packet->_edns_z = z;
+}
+
+void
+ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data)
+{
+	packet->_edns_data = data;
+}
+
+void
+ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count)
+{
+	switch(s) {
+		case LDNS_SECTION_QUESTION:
+			ldns_pkt_set_qdcount(packet, count);
+			break;
+		case LDNS_SECTION_ANSWER:
+			ldns_pkt_set_ancount(packet, count);
+			break;
+		case LDNS_SECTION_AUTHORITY:
+			ldns_pkt_set_nscount(packet, count);
+			break;
+		case LDNS_SECTION_ADDITIONAL:
+			ldns_pkt_set_arcount(packet, count);
+			break;
+		case LDNS_SECTION_ANY:
+		case LDNS_SECTION_ANY_NOQUESTION:
+			break;
+	}
+}
+
+void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr)
+{
+	pkt->_tsig_rr = rr;
+}
+
+bool
+ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr)
+{
+	switch(section) {
+		case LDNS_SECTION_QUESTION:
+			if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
+				return false;
+			}
+			ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1);
+			break;
+		case LDNS_SECTION_ANSWER:
+			if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
+				return false;
+			}
+			ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1);
+			break;
+		case LDNS_SECTION_AUTHORITY:
+			if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
+				return false;
+			}
+			ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1);
+			break;
+		case LDNS_SECTION_ADDITIONAL:
+			if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
+				return false;
+			}
+			ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1);
+			break;
+		case LDNS_SECTION_ANY:
+		case LDNS_SECTION_ANY_NOQUESTION:
+			/* shouldn't this error? */
+			break;
+	}
+	return true;
+}
+
+bool
+ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
+{
+
+	/* check to see if its there */
+	if (ldns_pkt_rr(pkt, sec, rr)) {
+		/* already there */
+		return false;
+	}
+	return ldns_pkt_push_rr(pkt, sec, rr);
+}
+
+bool
+ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
+{
+	size_t i;
+	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
+		if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) {
+			return false;
+		}
+	}
+	return true;
+}
+
+bool
+ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
+{
+	size_t i;
+	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
+		if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) {
+			return false;
+		}
+	}
+	return true;
+}
+
+bool
+ldns_pkt_edns(const ldns_pkt *pkt) {
+	return (ldns_pkt_edns_udp_size(pkt) > 0 ||
+		ldns_pkt_edns_extended_rcode(pkt) > 0 ||
+		ldns_pkt_edns_data(pkt) ||
+		ldns_pkt_edns_do(pkt) ||
+                pkt->_edns_present
+	       );
+}
+
+
+/* Create/destroy/convert functions
+ */
+ldns_pkt *
+ldns_pkt_new(void)
+{
+	ldns_pkt *packet;
+	packet = LDNS_MALLOC(ldns_pkt);
+	if (!packet) {
+		return NULL;
+	}
+
+	packet->_header = LDNS_MALLOC(ldns_hdr);
+	if (!packet->_header) {
+		LDNS_FREE(packet);
+		return NULL;
+	}
+
+	packet->_question = ldns_rr_list_new();
+	packet->_answer = ldns_rr_list_new();
+	packet->_authority = ldns_rr_list_new();
+	packet->_additional = ldns_rr_list_new();
+
+	/* default everything to false */
+	ldns_pkt_set_qr(packet, false);
+	ldns_pkt_set_aa(packet, false);
+	ldns_pkt_set_tc(packet, false);
+	ldns_pkt_set_rd(packet, false);
+	ldns_pkt_set_ra(packet, false);
+	ldns_pkt_set_ad(packet, false);
+	ldns_pkt_set_cd(packet, false);
+
+	ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY);
+	ldns_pkt_set_rcode(packet, 0);
+	ldns_pkt_set_id(packet, 0); 
+	ldns_pkt_set_size(packet, 0);
+	ldns_pkt_set_querytime(packet, 0);
+	memset(&packet->timestamp, 0, sizeof(packet->timestamp));
+	ldns_pkt_set_answerfrom(packet, NULL);
+	ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0);
+	ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0);
+	ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0);
+	ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0);
+	
+	ldns_pkt_set_edns_udp_size(packet, 0);
+	ldns_pkt_set_edns_extended_rcode(packet, 0);
+	ldns_pkt_set_edns_version(packet, 0);
+	ldns_pkt_set_edns_z(packet, 0);
+	ldns_pkt_set_edns_data(packet, NULL);
+	packet->_edns_present = false;
+	
+	ldns_pkt_set_tsig(packet, NULL);
+	
+	return packet;
+}
+
+void
+ldns_pkt_free(ldns_pkt *packet)
+{
+	if (packet) {
+		LDNS_FREE(packet->_header);
+		ldns_rr_list_deep_free(packet->_question);
+		ldns_rr_list_deep_free(packet->_answer);
+		ldns_rr_list_deep_free(packet->_authority);
+		ldns_rr_list_deep_free(packet->_additional);
+		ldns_rr_free(packet->_tsig_rr);
+		ldns_rdf_deep_free(packet->_edns_data);
+		ldns_rdf_deep_free(packet->_answerfrom);
+		LDNS_FREE(packet);
+	}
+}
+
+bool
+ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags)
+{
+	if (!packet) {
+		return false;
+	}
+	if ((flags & LDNS_QR) == LDNS_QR) {
+		ldns_pkt_set_qr(packet, true);
+	}
+	if ((flags & LDNS_AA) == LDNS_AA) {
+		ldns_pkt_set_aa(packet, true);
+	}
+	if ((flags & LDNS_RD) == LDNS_RD) {
+		ldns_pkt_set_rd(packet, true);
+	}
+	if ((flags & LDNS_TC) == LDNS_TC) {
+		ldns_pkt_set_tc(packet, true);
+	}
+	if ((flags & LDNS_CD) == LDNS_CD) {
+		ldns_pkt_set_cd(packet, true);
+	}
+	if ((flags & LDNS_RA) == LDNS_RA) {
+		ldns_pkt_set_ra(packet, true);
+	}
+	if ((flags & LDNS_AD) == LDNS_AD) {
+		ldns_pkt_set_ad(packet, true);
+	}
+	return true;
+}
+
+
+static ldns_rr*
+ldns_pkt_authsoa(ldns_rdf* rr_name, ldns_rr_class rr_class)
+{
+	ldns_rr* soa_rr = ldns_rr_new();
+	ldns_rdf *owner_rdf;
+	ldns_rdf *mname_rdf;
+	ldns_rdf *rname_rdf;
+	ldns_rdf *serial_rdf;
+	ldns_rdf *refresh_rdf;
+	ldns_rdf *retry_rdf;
+	ldns_rdf *expire_rdf;
+	ldns_rdf *minimum_rdf;
+
+	if (!soa_rr) {
+		return NULL;
+	}
+	owner_rdf = ldns_rdf_clone(rr_name);
+	if (!owner_rdf) {
+		ldns_rr_free(soa_rr);
+		return NULL;
+	}
+
+	ldns_rr_set_owner(soa_rr, owner_rdf);
+	ldns_rr_set_type(soa_rr, LDNS_RR_TYPE_SOA);
+	ldns_rr_set_class(soa_rr, rr_class);
+	ldns_rr_set_question(soa_rr, false);
+
+	if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
+		ldns_rr_free(soa_rr);
+		return NULL;
+	} else {
+		ldns_rr_push_rdf(soa_rr, mname_rdf);
+	}
+	if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
+		ldns_rr_free(soa_rr);
+		return NULL;
+	} else {
+		ldns_rr_push_rdf(soa_rr, rname_rdf);
+	}
+	serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+	if (!serial_rdf) {
+		ldns_rr_free(soa_rr);
+		return NULL;
+	} else {
+		ldns_rr_push_rdf(soa_rr, serial_rdf);
+	}
+	refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+	if (!refresh_rdf) {
+		ldns_rr_free(soa_rr);
+		return NULL;
+	} else {
+		ldns_rr_push_rdf(soa_rr, refresh_rdf);
+	}
+	retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+	if (!retry_rdf) {
+		ldns_rr_free(soa_rr);
+		return NULL;
+	} else {
+		ldns_rr_push_rdf(soa_rr, retry_rdf);
+	}
+	expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+	if (!expire_rdf) {
+		ldns_rr_free(soa_rr);
+		return NULL;
+	} else {
+		ldns_rr_push_rdf(soa_rr, expire_rdf);
+	}
+	minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+	if (!minimum_rdf) {
+		ldns_rr_free(soa_rr);
+		return NULL;
+	} else {
+		ldns_rr_push_rdf(soa_rr, minimum_rdf);
+	}
+	return soa_rr;
+}
+
+
+static ldns_status
+ldns_pkt_query_new_frm_str_internal(ldns_pkt **p, const char *name,
+	ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags,
+	ldns_rr* authsoa_rr)
+{
+	ldns_pkt *packet;
+	ldns_rr *question_rr;
+	ldns_rdf *name_rdf;
+
+	packet = ldns_pkt_new();
+	if (!packet) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	if (!ldns_pkt_set_flags(packet, flags)) {
+		return LDNS_STATUS_ERR;
+	}
+
+	question_rr = ldns_rr_new();
+	if (!question_rr) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	if (rr_type == 0) {
+		rr_type = LDNS_RR_TYPE_A;
+	}
+	if (rr_class == 0) {
+		rr_class = LDNS_RR_CLASS_IN;
+	}
+
+	if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
+		ldns_rr_set_owner(question_rr, name_rdf);
+		ldns_rr_set_type(question_rr, rr_type);
+		ldns_rr_set_class(question_rr, rr_class);
+                ldns_rr_set_question(question_rr, true);
+
+		ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
+	} else {
+		ldns_rr_free(question_rr);
+		ldns_pkt_free(packet);
+		return LDNS_STATUS_ERR;
+	}
+
+	if (authsoa_rr) {
+		ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
+	}
+
+	packet->_tsig_rr = NULL;
+	ldns_pkt_set_answerfrom(packet, NULL);
+	if (p) {
+		*p = packet;
+		return LDNS_STATUS_OK;
+	} else {
+		ldns_pkt_free(packet);
+		return LDNS_STATUS_NULL;
+	}
+}
+
+ldns_status
+ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name,
+	ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags)
+{
+	return ldns_pkt_query_new_frm_str_internal(p, name, rr_type,
+		rr_class, flags, NULL);
+}
+
+ldns_status
+ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *name,
+	ldns_rr_class rr_class, uint16_t flags, ldns_rr *soa)
+{
+	ldns_rr* authsoa_rr = soa;
+	if (!authsoa_rr) {
+		ldns_rdf *name_rdf;
+		if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
+			authsoa_rr = ldns_pkt_authsoa(name_rdf, rr_class);
+		}
+		ldns_rdf_free(name_rdf);
+	}
+	return ldns_pkt_query_new_frm_str_internal(p, name, LDNS_RR_TYPE_IXFR,
+		rr_class, flags, authsoa_rr);
+}
+
+static ldns_pkt *
+ldns_pkt_query_new_internal(ldns_rdf *rr_name, ldns_rr_type rr_type,
+	ldns_rr_class rr_class,	uint16_t flags, ldns_rr* authsoa_rr)
+{
+	ldns_pkt *packet;
+	ldns_rr *question_rr;
+
+	packet = ldns_pkt_new();
+	if (!packet) {
+		return NULL;
+	}
+
+	if (!ldns_pkt_set_flags(packet, flags)) {
+		return NULL;
+	}
+
+	question_rr = ldns_rr_new();
+	if (!question_rr) {
+		ldns_pkt_free(packet);
+		return NULL;
+	}
+
+	if (rr_type == 0) {
+		rr_type = LDNS_RR_TYPE_A;
+	}
+	if (rr_class == 0) {
+		rr_class = LDNS_RR_CLASS_IN;
+	}
+
+	ldns_rr_set_owner(question_rr, rr_name);
+	ldns_rr_set_type(question_rr, rr_type);
+	ldns_rr_set_class(question_rr, rr_class);
+        ldns_rr_set_question(question_rr, true);
+	ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
+
+	if (authsoa_rr) {
+		ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
+	}
+
+	packet->_tsig_rr = NULL;
+	return packet;
+}
+
+ldns_pkt *
+ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type,
+	ldns_rr_class rr_class,	uint16_t flags)
+{
+	return ldns_pkt_query_new_internal(rr_name, rr_type,
+		rr_class, flags, NULL);
+}
+
+ldns_pkt *
+ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class,
+	uint16_t flags, ldns_rr* soa)
+{
+	ldns_rr* authsoa_rr = soa;
+	if (!authsoa_rr) {
+		authsoa_rr = ldns_pkt_authsoa(rr_name, rr_class);
+	}
+	return ldns_pkt_query_new_internal(rr_name, LDNS_RR_TYPE_IXFR,
+		rr_class, flags, authsoa_rr);
+}
+
+ldns_pkt_type
+ldns_pkt_reply_type(ldns_pkt *p)
+{
+	ldns_rr_list *tmp;
+
+	if (!p) {
+		return LDNS_PACKET_UNKNOWN;
+	}
+
+	if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) {
+		return LDNS_PACKET_NXDOMAIN;
+	}
+
+	if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0
+			&& ldns_pkt_nscount(p) == 1) {
+
+		/* check for SOA */
+		tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, 
+					LDNS_SECTION_AUTHORITY);
+		if (tmp) {
+			ldns_rr_list_deep_free(tmp);
+			return LDNS_PACKET_NODATA;
+		} else {
+			/* I have no idea ... */
+		}
+	}
+
+	if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) {
+		tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS,
+		                               LDNS_SECTION_AUTHORITY);
+		if (tmp) {
+			/* there are nameservers here */
+			ldns_rr_list_deep_free(tmp);
+			return LDNS_PACKET_REFERRAL;
+		} else {
+			/* I have no idea */
+		}
+		ldns_rr_list_deep_free(tmp);
+	}
+	
+	/* if we cannot determine the packet type, we say it's an 
+	 * answer...
+	 */
+	return LDNS_PACKET_ANSWER;
+}
+
+ldns_pkt *
+ldns_pkt_clone(const ldns_pkt *pkt)
+{
+	ldns_pkt *new_pkt;
+	
+	if (!pkt) {
+		return NULL;
+	}
+	new_pkt = ldns_pkt_new();
+
+	ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt));
+	ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt));
+	ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt));
+	ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt));
+	ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt));
+	ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt));
+	ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt));
+	ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt));
+	ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt));
+	ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt));
+	ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt));
+	ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt));
+	ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt));
+	ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt));
+	if (ldns_pkt_answerfrom(pkt))
+		ldns_pkt_set_answerfrom(new_pkt,
+			ldns_rdf_clone(ldns_pkt_answerfrom(pkt)));
+	ldns_pkt_set_timestamp(new_pkt, ldns_pkt_timestamp(pkt));
+	ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
+	ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
+	ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt)));
+	
+	ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt));
+	ldns_pkt_set_edns_extended_rcode(new_pkt, 
+		ldns_pkt_edns_extended_rcode(pkt));
+	ldns_pkt_set_edns_version(new_pkt, ldns_pkt_edns_version(pkt));
+	new_pkt->_edns_present = pkt->_edns_present;
+	ldns_pkt_set_edns_z(new_pkt, ldns_pkt_edns_z(pkt));
+	if(ldns_pkt_edns_data(pkt))
+		ldns_pkt_set_edns_data(new_pkt, 
+			ldns_rdf_clone(ldns_pkt_edns_data(pkt)));
+	ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt));
+
+	ldns_rr_list_deep_free(new_pkt->_question);
+	ldns_rr_list_deep_free(new_pkt->_answer);
+	ldns_rr_list_deep_free(new_pkt->_authority);
+	ldns_rr_list_deep_free(new_pkt->_additional);
+	new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt));
+	new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt));
+	new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt));
+	new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt));
+	return new_pkt;
+}
diff --git a/ldns/src/parse.c b/ldns/src/parse.c
new file mode 100644
index 0000000..e68627c
--- /dev/null
+++ b/ldns/src/parse.c
@@ -0,0 +1,434 @@
+/*
+ * a generic (simple) parser. Use to parse rr's, private key
+ * information and /etc/resolv.conf files
+ *
+ * a Net::DNS like library for C
+ * LibDNS Team @ NLnet Labs
+ * (c) NLnet Labs, 2005-2006
+ * See the file LICENSE for the license
+ */
+#include <ldns/config.h>
+#include <ldns/ldns.h>
+
+#include <limits.h>
+#include <strings.h>
+
+ldns_lookup_table ldns_directive_types[] = {
+        { LDNS_DIR_TTL, "$TTL" },
+        { LDNS_DIR_ORIGIN, "$ORIGIN" },
+        { LDNS_DIR_INCLUDE, "$INCLUDE" },
+        { 0, NULL }
+};
+
+/* add max_limit here? */
+ssize_t
+ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit)
+{
+	return ldns_fget_token_l(f, token, delim, limit, NULL);
+}
+
+ssize_t
+ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
+{
+	int c, prev_c;
+	int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
+	int com, quoted;
+	char *t;
+	size_t i;
+	const char *d;
+	const char *del;
+
+	/* standard delimeters */
+	if (!delim) {
+		/* from isspace(3) */
+		del = LDNS_PARSE_NORMAL;
+	} else {
+		del = delim;
+	}
+
+	p = 0;
+	i = 0;
+	com = 0;
+	quoted = 0;
+	prev_c = 0;
+	t = token;
+	if (del[0] == '"') {
+		quoted = 1;
+	}
+	while ((c = getc(f)) != EOF) {
+		if (c == '\r') /* carriage return */
+			c = ' ';
+		if (c == '(' && prev_c != '\\' && !quoted) {
+			/* this only counts for non-comments */
+			if (com == 0) {
+				p++;
+			}
+			prev_c = c;
+			continue;
+		}
+
+		if (c == ')' && prev_c != '\\' && !quoted) {
+			/* this only counts for non-comments */
+			if (com == 0) {
+				p--;
+			}
+			prev_c = c;
+			continue;
+		}
+
+		if (p < 0) {
+			/* more ) then ( - close off the string */
+			*t = '\0';
+			return 0;
+		}
+
+		/* do something with comments ; */
+		if (c == ';' && quoted == 0) {
+			if (prev_c != '\\') {
+				com = 1;
+			}
+		}
+		if (c == '\"' && com == 0 && prev_c != '\\') {
+			quoted = 1 - quoted;
+		}
+
+		if (c == '\n' && com != 0) {
+			/* comments */
+			com = 0;
+			*t = ' ';
+			if (line_nr) {
+				*line_nr = *line_nr + 1;
+			}
+			if (p == 0 && i > 0) {
+				goto tokenread;
+			} else {
+				prev_c = c;
+				continue;
+			}
+		}
+
+		if (com == 1) {
+			*t = ' ';
+			prev_c = c;
+			continue;
+		}
+
+		if (c == '\n' && p != 0 && t > token) {
+			/* in parentheses */
+			if (line_nr) {
+				*line_nr = *line_nr + 1;
+			}
+			*t++ = ' ';
+			prev_c = c;
+			continue;
+		}
+
+		/* check if we hit the delim */
+		for (d = del; *d; d++) {
+			if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
+				if (c == '\n' && line_nr) {
+					*line_nr = *line_nr + 1;
+				}
+				goto tokenread;
+			}
+		}
+		if (c != '\0' && c != '\n') {
+			i++;
+		}
+		if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
+			*t = '\0';
+			return -1;
+		}
+		if (c != '\0' && c != '\n') {
+			*t++ = c;
+		}
+		if (c == '\\' && prev_c == '\\')
+			prev_c = 0;
+		else	prev_c = c;
+	}
+	*t = '\0';
+	if (c == EOF) {
+		return (ssize_t)i;
+	}
+
+	if (i == 0) {
+		/* nothing read */
+		return -1;
+	}
+	if (p != 0) {
+		return -1;
+	}
+	return (ssize_t)i;
+
+tokenread:
+	if(*del == '"') /* do not skip over quotes, they are significant */
+		ldns_fskipcs_l(f, del+1, line_nr);
+	else	ldns_fskipcs_l(f, del, line_nr);
+	*t = '\0';
+	if (p != 0) {
+		return -1;
+	}
+
+	return (ssize_t)i;
+}
+
+ssize_t
+ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data,
+               const char *d_del, size_t data_limit)
+{
+       return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del,
+		       data_limit, NULL);
+}
+
+ssize_t
+ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data,
+               const char *d_del, size_t data_limit, int *line_nr)
+{
+       /* we assume: keyword|sep|data */
+       char *fkeyword;
+       ssize_t i;
+
+       if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
+               return -1;
+       fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
+       if(!fkeyword)
+               return -1;
+
+       i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
+       if(i==0 || i==-1) {
+               LDNS_FREE(fkeyword);
+               return -1;
+       }
+
+       /* case??? i instead of strlen? */
+       if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
+               /* whee! */
+               /* printf("%s\n%s\n", "Matching keyword", fkeyword); */
+               i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr);
+               LDNS_FREE(fkeyword);
+               return i;
+       } else {
+               /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/
+               LDNS_FREE(fkeyword);
+               return -1;
+       }
+}
+
+
+ssize_t
+ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
+{
+	int c, lc;
+	int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
+	int com, quoted;
+	char *t;
+	size_t i;
+	const char *d;
+	const char *del;
+
+	/* standard delimiters */
+	if (!delim) {
+		/* from isspace(3) */
+		del = LDNS_PARSE_NORMAL;
+	} else {
+		del = delim;
+	}
+
+	p = 0;
+	i = 0;
+	com = 0;
+	quoted = 0;
+	t = token;
+	lc = 0;
+	if (del[0] == '"') {
+		quoted = 1;
+	}
+
+	while ((c = ldns_bgetc(b)) != EOF) {
+		if (c == '\r') /* carriage return */
+			c = ' ';
+		if (c == '(' && lc != '\\' && !quoted) {
+			/* this only counts for non-comments */
+			if (com == 0) {
+				p++;
+			}
+			lc = c;
+			continue;
+		}
+
+		if (c == ')' && lc != '\\' && !quoted) {
+			/* this only counts for non-comments */
+			if (com == 0) {
+				p--;
+			}
+			lc = c;
+			continue;
+		}
+
+		if (p < 0) {
+			/* more ) then ( */
+			*t = '\0';
+			return 0;
+		}
+
+		/* do something with comments ; */
+		if (c == ';' && quoted == 0) {
+			if (lc != '\\') {
+				com = 1;
+			}
+		}
+		if (c == '"' && com == 0 && lc != '\\') {
+			quoted = 1 - quoted;
+		}
+
+		if (c == '\n' && com != 0) {
+			/* comments */
+			com = 0;
+			*t = ' ';
+			lc = c;
+			continue;
+		}
+
+		if (com == 1) {
+			*t = ' ';
+			lc = c;
+			continue;
+		}
+
+		if (c == '\n' && p != 0) {
+			/* in parentheses */
+			*t++ = ' ';
+			lc = c;
+			continue;
+		}
+
+		/* check if we hit the delim */
+		for (d = del; *d; d++) {
+                        if (c == *d && lc != '\\' && p == 0) {
+				goto tokenread;
+                        }
+		}
+
+		i++;
+		if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
+			*t = '\0';
+			return -1;
+		}
+		*t++ = c;
+
+		if (c == '\\' && lc == '\\') {
+			lc = 0;
+		} else {
+			lc = c;
+		}
+	}
+	*t = '\0';
+	if (i == 0) {
+		/* nothing read */
+		return -1;
+	}
+	if (p != 0) {
+		return -1;
+	}
+	return (ssize_t)i;
+
+tokenread:
+	if(*del == '"') /* do not skip over quotes, they are significant */
+		ldns_bskipcs(b, del+1);
+	else	ldns_bskipcs(b, del);
+	*t = '\0';
+
+	if (p != 0) {
+		return -1;
+	}
+	return (ssize_t)i;
+}
+
+
+void
+ldns_bskipcs(ldns_buffer *buffer, const char *s)
+{
+        bool found;
+        char c;
+        const char *d;
+
+        while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) {
+                c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position);
+                found = false;
+                for (d = s; *d; d++) {
+                        if (*d == c) {
+                                found = true;
+                        }
+                }
+                if (found && buffer->_limit > buffer->_position) {
+                        buffer->_position += sizeof(char);
+                } else {
+                        return;
+                }
+        }
+}
+
+void
+ldns_fskipcs(FILE *fp, const char *s)
+{
+	ldns_fskipcs_l(fp, s, NULL);
+}
+
+void
+ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr)
+{
+        bool found;
+        int c;
+        const char *d;
+
+	while ((c = fgetc(fp)) != EOF) {
+		if (line_nr && c == '\n') {
+			*line_nr = *line_nr + 1;
+		}
+                found = false;
+                for (d = s; *d; d++) {
+                        if (*d == c) {
+                                found = true;
+                        }
+                }
+		if (!found) {
+			/* with getc, we've read too far */
+			ungetc(c, fp);
+			return;
+		}
+	}
+}
+
+ssize_t
+ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char
+*data, const char *d_del, size_t data_limit)
+{
+       /* we assume: keyword|sep|data */
+       char *fkeyword;
+       ssize_t i;
+
+       if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
+               return -1;
+       fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
+       if(!fkeyword)
+               return -1; /* out of memory */
+
+       i = ldns_bget_token(b, fkeyword, k_del, data_limit);
+       if(i==0 || i==-1) {
+               LDNS_FREE(fkeyword);
+               return -1; /* nothing read */
+       }
+
+       /* case??? */
+       if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
+               LDNS_FREE(fkeyword);
+               /* whee, the match! */
+               /* retrieve it's data */
+               i = ldns_bget_token(b, data, d_del, 0);
+               return i;
+       } else {
+               LDNS_FREE(fkeyword);
+               return -1;
+       }
+}
+
diff --git a/ldns/src/radix.c b/ldns/src/radix.c
new file mode 100644
index 0000000..7aac258
--- /dev/null
+++ b/ldns/src/radix.c
@@ -0,0 +1,1590 @@
+/*
+ * radix.c -- generic radix tree
+ *
+ * Taken from NSD4, modified for ldns
+ *
+ * Copyright (c) 2012, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file
+ * Implementation of a radix tree.
+ */
+
+#include <ldns/config.h>
+#include <ldns/radix.h>
+#include <ldns/util.h>
+#include <stdlib.h>
+
+/** Helper functions */
+static ldns_radix_node_t* ldns_radix_new_node(void* data, uint8_t* key,
+	radix_strlen_t len);
+static int ldns_radix_find_prefix(ldns_radix_t* tree, uint8_t* key,
+	radix_strlen_t len, ldns_radix_node_t** result, radix_strlen_t* pos);
+static int ldns_radix_array_space(ldns_radix_node_t* node, uint8_t byte);
+static int ldns_radix_array_grow(ldns_radix_node_t* node, unsigned need);
+static int ldns_radix_str_create(ldns_radix_array_t* array, uint8_t* key,
+	radix_strlen_t pos, radix_strlen_t len);
+static int ldns_radix_prefix_remainder(radix_strlen_t prefix_len,
+	uint8_t* longer_str, radix_strlen_t longer_len, uint8_t** split_str,
+	radix_strlen_t* split_len);
+static int ldns_radix_array_split(ldns_radix_array_t* array, uint8_t* key,
+	radix_strlen_t pos, radix_strlen_t len, ldns_radix_node_t* add);
+static int ldns_radix_str_is_prefix(uint8_t* str1, radix_strlen_t len1,
+	uint8_t* str2, radix_strlen_t len2);
+static radix_strlen_t ldns_radix_str_common(uint8_t* str1, radix_strlen_t len1,
+	uint8_t* str2, radix_strlen_t len2);
+static ldns_radix_node_t* ldns_radix_next_in_subtree(ldns_radix_node_t* node);
+static ldns_radix_node_t* ldns_radix_prev_from_index(ldns_radix_node_t* node,
+	uint8_t index);
+static ldns_radix_node_t* ldns_radix_last_in_subtree_incl_self(
+	ldns_radix_node_t* node);
+static ldns_radix_node_t* ldns_radix_last_in_subtree(ldns_radix_node_t* node);
+static void ldns_radix_del_fix(ldns_radix_t* tree, ldns_radix_node_t* node);
+static void ldns_radix_cleanup_onechild(ldns_radix_node_t* node);
+static void ldns_radix_cleanup_leaf(ldns_radix_node_t* node);
+static void ldns_radix_node_free(ldns_radix_node_t* node, void* arg);
+static void ldns_radix_node_array_free(ldns_radix_node_t* node);
+static void ldns_radix_node_array_free_front(ldns_radix_node_t* node);
+static void ldns_radix_node_array_free_end(ldns_radix_node_t* node);
+static void ldns_radix_array_reduce(ldns_radix_node_t* node);
+static void ldns_radix_self_or_prev(ldns_radix_node_t* node,
+	ldns_radix_node_t** result);
+
+
+/**
+ * Create a new radix node.
+ *
+ */
+static ldns_radix_node_t*
+ldns_radix_new_node(void* data, uint8_t* key, radix_strlen_t len)
+{
+	ldns_radix_node_t* node = LDNS_MALLOC(ldns_radix_node_t);
+	if (!node) {
+		return NULL;
+	}
+	node->data = data;
+	node->key = key;
+	node->klen = len;
+	node->parent = NULL;
+	node->parent_index = 0;
+	node->len = 0;
+	node->offset = 0;
+	node->capacity = 0;
+	node->array = NULL;
+	return node;
+}
+
+
+/**
+ * Create a new radix tree.
+ *
+ */
+ldns_radix_t *
+ldns_radix_create(void)
+{
+	ldns_radix_t* tree;
+
+	/** Allocate memory for it */
+	tree = (ldns_radix_t *) LDNS_MALLOC(ldns_radix_t);
+	if (!tree) {
+		return NULL;
+	}
+	/** Initialize it */
+	ldns_radix_init(tree);
+	return tree;
+}
+
+
+/**
+ * Initialize radix tree.
+ *
+ */
+void
+ldns_radix_init(ldns_radix_t* tree)
+{
+	/** Initialize it */
+	if (tree) {
+		tree->root = NULL;
+		tree->count = 0;
+	}
+	return;
+}
+
+
+/**
+ * Free radix tree.
+ *
+ */
+void
+ldns_radix_free(ldns_radix_t* tree)
+{
+	if (tree) {
+		if (tree->root) {
+			ldns_radix_traverse_postorder(tree->root,
+				ldns_radix_node_free, NULL);
+		}
+		LDNS_FREE(tree);
+	}
+	return;
+}
+
+
+/**
+ * Insert data into the tree.
+ *
+ */
+ldns_status
+ldns_radix_insert(ldns_radix_t* tree, uint8_t* key, radix_strlen_t len,
+	void* data)
+{
+	radix_strlen_t pos = 0;
+	ldns_radix_node_t* add = NULL;
+	ldns_radix_node_t* prefix = NULL;
+
+	if (!tree || !key || !data) {
+		return LDNS_STATUS_NULL;
+	}
+	add = ldns_radix_new_node(data, key, len);
+	if (!add) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	/** Search the trie until we can make no further process. */
+	if (!ldns_radix_find_prefix(tree, key, len, &prefix, &pos)) {
+		/** No prefix found */
+		assert(tree->root == NULL);
+		if (len == 0) {
+			/**
+			 * Example 1: The root:
+			 * | [0]
+			 **/
+			tree->root = add;
+		} else {
+			/** Example 2: 'dns':
+			 * | [0]
+			 * --| [d+ns] dns
+			 **/
+			prefix = ldns_radix_new_node(NULL, (uint8_t*)"", 0);
+			if (!prefix) {
+				LDNS_FREE(add);
+				return LDNS_STATUS_MEM_ERR;
+			}
+			/** Find some space in the array for the first byte */
+			if (!ldns_radix_array_space(prefix, key[0])) {
+				LDNS_FREE(add);
+				LDNS_FREE(prefix->array);
+				LDNS_FREE(prefix);
+				return LDNS_STATUS_MEM_ERR;
+			}
+			/** Set relational pointers */
+			add->parent = prefix;
+			add->parent_index = 0;
+			prefix->array[0].edge = add;
+			if (len > 1) {
+				/** Store the remainder of the prefix */
+				if (!ldns_radix_prefix_remainder(1, key,
+					len, &prefix->array[0].str,
+					&prefix->array[0].len)) {
+					LDNS_FREE(add);
+					LDNS_FREE(prefix->array);
+					LDNS_FREE(prefix);
+					return LDNS_STATUS_MEM_ERR;
+				}
+			}
+			tree->root = prefix;
+		}
+	} else if (pos == len) {
+		/** Exact match found */
+		if (prefix->data) {
+			/* Element already exists */
+			LDNS_FREE(add);
+			return LDNS_STATUS_EXISTS_ERR;
+		}
+		prefix->data = data;
+		prefix->key = key;
+		prefix->klen = len; /* redundant */
+	} else {
+		/** Prefix found */
+		uint8_t byte = key[pos];
+		assert(pos < len);
+		if (byte < prefix->offset ||
+			(byte - prefix->offset) >= prefix->len) {
+			/** Find some space in the array for the byte. */
+			/**
+			 * Example 3: 'ldns'
+			 * | [0]
+			 * --| [d+ns] dns
+			 * --| [l+dns] ldns
+			 **/
+			if (!ldns_radix_array_space(prefix, byte)) {
+				LDNS_FREE(add);
+				return LDNS_STATUS_MEM_ERR;
+			}
+			assert(byte >= prefix->offset);
+			assert((byte - prefix->offset) <= prefix->len);
+			byte -= prefix->offset;
+			if (pos+1 < len) {
+				/** Create remainder of the string. */
+				if (!ldns_radix_str_create(
+					&prefix->array[byte], key, pos+1,
+					len)) {
+					LDNS_FREE(add);
+					return LDNS_STATUS_MEM_ERR;
+				}
+			}
+			/** Add new node. */
+			add->parent = prefix;
+			add->parent_index = byte;
+			prefix->array[byte].edge = add;
+		} else if (prefix->array[byte-prefix->offset].edge == NULL) {
+			/** Use existing element. */
+			/**
+			 * Example 4: 'edns'
+			 * | [0]
+			 * --| [d+ns] dns
+			 * --| [e+dns] edns
+			 * --| [l+dns] ldns
+			 **/
+			byte -= prefix->offset;
+			if (pos+1 < len) {
+				/** Create remainder of the string. */
+				if (!ldns_radix_str_create(
+					&prefix->array[byte], key, pos+1,
+					len)) {
+					LDNS_FREE(add);
+					return LDNS_STATUS_MEM_ERR;
+				}
+			}
+			/** Add new node. */
+			add->parent = prefix;
+			add->parent_index = byte;
+			prefix->array[byte].edge = add;
+		} else {
+			/**
+			 * Use existing element, but it has a shared prefix,
+			 * we need a split.
+			 */
+			if (!ldns_radix_array_split(&prefix->array[byte-(prefix->offset)],
+				key, pos+1, len, add)) {
+				LDNS_FREE(add);
+				return LDNS_STATUS_MEM_ERR;
+			}
+		}
+	}
+
+	tree->count ++;
+	return LDNS_STATUS_OK;
+}
+
+
+/**
+ * Delete data from the tree.
+ *
+ */
+void* ldns_radix_delete(ldns_radix_t* tree, uint8_t* key, radix_strlen_t len)
+{
+    ldns_radix_node_t* del = ldns_radix_search(tree, key, len);
+    void* data = NULL;
+    if (del) {
+        tree->count--;
+        data = del->data;
+        del->data = NULL;
+        ldns_radix_del_fix(tree, del);
+        return data;
+    }
+    return NULL;
+}
+
+
+/**
+ * Search data in the tree.
+ *
+ */
+ldns_radix_node_t*
+ldns_radix_search(ldns_radix_t* tree, uint8_t* key, radix_strlen_t len)
+{
+	ldns_radix_node_t* node = NULL;
+	radix_strlen_t pos = 0;
+	uint8_t byte = 0;
+
+	if (!tree || !key) {
+		return NULL;
+	}
+	node = tree->root;
+	while (node) {
+		if (pos == len) {
+			return node->data?node:NULL;
+		}
+		byte = key[pos];
+		if (byte < node->offset) {
+			return NULL;
+		}
+		byte -= node->offset;
+		if (byte >= node->len) {
+			return NULL;
+		}
+		pos++;
+		if (node->array[byte].len > 0) {
+			/** Must match additional string. */
+			if (pos + node->array[byte].len > len) {
+				return NULL;
+			}
+			if (memcmp(&key[pos], node->array[byte].str,
+				node->array[byte].len) != 0) {
+				return NULL;
+			}
+			pos += node->array[byte].len;
+		}
+		node = node->array[byte].edge;
+	}
+	return NULL;
+}
+
+
+/**
+ * Search data in the tree, and if not found, find the closest smaller
+ * element in the tree.
+ *
+ */
+int
+ldns_radix_find_less_equal(ldns_radix_t* tree, uint8_t* key,
+	radix_strlen_t len, ldns_radix_node_t** result)
+{
+	ldns_radix_node_t* node = NULL;
+	radix_strlen_t pos = 0;
+	uint8_t byte;
+	int memcmp_res = 0;
+
+	if (!tree || !tree->root || !key) {
+		*result = NULL;
+		return 0;
+	}
+
+	node = tree->root;
+	while (pos < len) {
+		byte = key[pos];
+		if (byte < node->offset) {
+			/**
+			 * No exact match. The lesser is in this or the
+			 * previous node.
+			 */
+			ldns_radix_self_or_prev(node, result);
+			return 0;
+		}
+		byte -= node->offset;
+		if (byte >= node->len) {
+			/**
+			 * No exact match. The lesser is in this node or the
+			 * last of this array, or something before this node.
+			 */
+			*result = ldns_radix_last_in_subtree_incl_self(node);
+			if (*result == NULL) {
+				*result = ldns_radix_prev(node);
+			}
+			return 0;
+		}
+		pos++;
+		if (!node->array[byte].edge) {
+			/**
+			 * No exact match. Find the previous in the array
+			 * from this index.
+			 */
+			*result = ldns_radix_prev_from_index(node, byte);
+			if (*result == NULL) {
+				ldns_radix_self_or_prev(node, result);
+			}
+			return 0;
+		}
+		if (node->array[byte].len != 0) {
+			/** Must match additional string. */
+			if (pos + node->array[byte].len > len) {
+				/** Additional string is longer than key. */
+				if (memcmp(&key[pos], node->array[byte].str,
+					len-pos) <= 0) {
+					/** Key is before this node. */
+					*result = ldns_radix_prev(
+						node->array[byte].edge);
+				} else {
+					/** Key is after additional string. */
+					*result = ldns_radix_last_in_subtree_incl_self(node->array[byte].edge);
+					if (*result == NULL) {
+						 *result = ldns_radix_prev(node->array[byte].edge);
+					}
+				}
+				return 0;
+			}
+			memcmp_res = memcmp(&key[pos], node->array[byte].str,
+				node->array[byte].len);
+			if (memcmp_res < 0) {
+				*result = ldns_radix_prev(
+					node->array[byte].edge);
+				return 0;
+			} else if (memcmp_res > 0) {
+				*result = ldns_radix_last_in_subtree_incl_self(node->array[byte].edge);
+				if (*result == NULL) {
+					 *result = ldns_radix_prev(node->array[byte].edge);
+				}
+				return 0;
+			}
+
+			pos += node->array[byte].len;
+		}
+		node = node->array[byte].edge;
+	}
+	if (node->data) {
+		/** Exact match. */
+		*result = node;
+		return 1;
+	}
+	/** There is a node which is an exact match, but has no element. */
+	*result = ldns_radix_prev(node);
+	return 0;
+}
+
+
+/**
+ * Get the first element in the tree.
+ *
+ */
+ldns_radix_node_t*
+ldns_radix_first(ldns_radix_t* tree)
+{
+	ldns_radix_node_t* first = NULL;
+	if (!tree || !tree->root) {
+		return NULL;
+	}
+	first = tree->root;
+	if (first->data) {
+		return first;
+	}
+	return ldns_radix_next(first);
+}
+
+
+/**
+ * Get the last element in the tree.
+ *
+ */
+ldns_radix_node_t*
+ldns_radix_last(ldns_radix_t* tree)
+{
+	if (!tree || !tree->root) {
+		return NULL;
+	}
+	return ldns_radix_last_in_subtree_incl_self(tree->root);
+}
+
+
+/**
+ * Next element.
+ *
+ */
+ldns_radix_node_t*
+ldns_radix_next(ldns_radix_node_t* node)
+{
+	if (!node) {
+		return NULL;
+	}
+	if (node->len) {
+		/** Go down: most-left child is the next. */
+		ldns_radix_node_t* next = ldns_radix_next_in_subtree(node);
+		if (next) {
+			return next;
+		}
+	}
+	/** No elements in subtree, get to parent and go down next branch. */
+	while (node->parent) {
+		uint8_t index = node->parent_index;
+		node = node->parent;
+		index++;
+		for (; index < node->len; index++) {
+			if (node->array[index].edge) {
+				ldns_radix_node_t* next;
+				/** Node itself. */
+				if (node->array[index].edge->data) {
+					return node->array[index].edge;
+				}
+				/** Dive into subtree. */
+				next = ldns_radix_next_in_subtree(node);
+				if (next) {
+					return next;
+				}
+			}
+		}
+	}
+	return NULL;
+}
+
+
+/**
+ * Previous element.
+ *
+ */
+ldns_radix_node_t*
+ldns_radix_prev(ldns_radix_node_t* node)
+{
+	if (!node) {
+		return NULL;
+	}
+
+	/** Get to parent and go down previous branch. */
+	while (node->parent) {
+		uint8_t index = node->parent_index;
+		ldns_radix_node_t* prev;
+		node = node->parent;
+		assert(node->len > 0);
+		prev = ldns_radix_prev_from_index(node, index);
+		if (prev) {
+			return prev;
+		}
+		if (node->data) {
+			return node;
+		}
+	}
+	return NULL;
+}
+
+
+/**
+ * Print node.
+ *
+ */
+static void
+ldns_radix_node_print(FILE* fd, ldns_radix_node_t* node,
+	uint8_t i, uint8_t* str, radix_strlen_t len, unsigned d)
+{
+	uint8_t j;
+	if (!node) {
+		return;
+	}
+	for (j = 0; j < d; j++) {
+		fprintf(fd, "--");
+	}
+	if (str) {
+		radix_strlen_t l;
+		fprintf(fd, "| [%u+", (unsigned) i);
+		for (l=0; l < len; l++) {
+			fprintf(fd, "%c", (char) str[l]);
+		}
+		fprintf(fd, "]%u", (unsigned) len);
+	} else {
+		fprintf(fd, "| [%u]", (unsigned) i);
+	}
+
+	if (node->data) {
+		fprintf(fd, " %s", (char*) node->data);
+	}
+	fprintf(fd, "\n");
+
+	for (j = 0; j < node->len; j++) {
+		if (node->array[j].edge) {
+			ldns_radix_node_print(fd, node->array[j].edge, j,
+				node->array[j].str, node->array[j].len, d+1);
+		}
+	}
+	return;
+}
+
+
+/**
+ * Print radix tree.
+ *
+ */
+void
+ldns_radix_printf(FILE* fd, ldns_radix_t* tree)
+{
+	if (!fd || !tree) {
+		return;
+	}
+	if (!tree->root) {
+		fprintf(fd, "; empty radix tree\n");
+		return;
+	}
+	ldns_radix_node_print(fd, tree->root, 0, NULL, 0, 0);
+	return;
+}
+
+
+/**
+ * Join two radix trees.
+ *
+ */
+ldns_status
+ldns_radix_join(ldns_radix_t* tree1, ldns_radix_t* tree2)
+{
+	ldns_radix_node_t* cur_node, *next_node;
+	ldns_status status;
+	if (!tree2 || !tree2->root) {
+		return LDNS_STATUS_OK;
+	}
+	/** Add all elements from tree2 into tree1. */
+
+	cur_node = ldns_radix_first(tree2);
+	while (cur_node) {
+		status = LDNS_STATUS_NO_DATA;
+		/** Insert current node into tree1 */
+		if (cur_node->data) {
+			status = ldns_radix_insert(tree1, cur_node->key,
+				cur_node->klen, cur_node->data);
+			/** Exist errors may occur */
+			if (status != LDNS_STATUS_OK &&
+			    status != LDNS_STATUS_EXISTS_ERR) {
+				return status;
+			}
+		}
+		next_node = ldns_radix_next(cur_node);
+		if (status == LDNS_STATUS_OK) {
+			(void) ldns_radix_delete(tree2, cur_node->key,
+				cur_node->klen);
+		}
+		cur_node = next_node;
+	}
+
+	return LDNS_STATUS_OK;
+}
+
+
+/**
+ * Split a radix tree intwo.
+ *
+ */
+ldns_status
+ldns_radix_split(ldns_radix_t* tree1, size_t num, ldns_radix_t** tree2)
+{
+	size_t count = 0;
+	ldns_radix_node_t* cur_node;
+	ldns_status status = LDNS_STATUS_OK;
+	if (!tree1 || !tree1->root || num == 0) {
+		return LDNS_STATUS_OK;
+	}
+	if (!tree2) {
+		return LDNS_STATUS_NULL;
+	}
+	if (!*tree2) {
+		*tree2 = ldns_radix_create();
+		if (!*tree2) {
+			return LDNS_STATUS_MEM_ERR;
+		}
+	}
+	cur_node = ldns_radix_first(tree1);
+	while (count < num && cur_node) {
+		if (cur_node->data) {
+			/** Delete current node from tree1. */
+			uint8_t* cur_key = cur_node->key;
+			radix_strlen_t cur_len = cur_node->klen;
+			void* cur_data = ldns_radix_delete(tree1, cur_key,
+				cur_len);
+			/** Insert current node into tree2/ */
+			if (!cur_data) {
+				return LDNS_STATUS_NO_DATA;
+			}
+			status = ldns_radix_insert(*tree2, cur_key, cur_len,
+				cur_data);
+			if (status != LDNS_STATUS_OK &&
+			    status != LDNS_STATUS_EXISTS_ERR) {
+				return status;
+			}
+/*
+			if (status == LDNS_STATUS_OK) {
+				cur_node->key = NULL;
+				cur_node->klen = 0;
+			}
+*/
+			/** Update count; get first element from tree1 again. */
+			count++;
+			cur_node = ldns_radix_first(tree1);
+		} else {
+			cur_node = ldns_radix_next(cur_node);
+		}
+	}
+	return LDNS_STATUS_OK;
+}
+
+
+/**
+ * Call function for all nodes in the tree, such that leaf nodes are
+ * called before parent nodes.
+ *
+ */
+void
+ldns_radix_traverse_postorder(ldns_radix_node_t* node,
+	void (*func)(ldns_radix_node_t*, void*), void* arg)
+{
+	uint8_t i;
+	if (!node) {
+		return;
+	}
+	for (i=0; i < node->len; i++) {
+		ldns_radix_traverse_postorder(node->array[i].edge,
+			func, arg);
+	}
+	/** Call user function */
+	(*func)(node, arg);
+	return;
+}
+
+
+/** Static helper functions */
+
+/**
+ * Find a prefix of the key.
+ * @param tree:   tree.
+ * @param key:    key.
+ * @param len:    length of key.
+ * @param result: the longest prefix, the entry itself if *pos==len,
+ *                otherwise an array entry.
+ * @param pos:    position in string where next unmatched byte is.
+ *                If *pos==len, an exact match is found.
+ *                If *pos== 0, a "" match was found.
+ * @return 0 (false) if no prefix found.
+ *
+ */
+static int
+ldns_radix_find_prefix(ldns_radix_t* tree, uint8_t* key,
+	radix_strlen_t len, ldns_radix_node_t** result, radix_strlen_t* respos)
+{
+	/** Start searching at the root node */
+	ldns_radix_node_t* n = tree->root;
+	radix_strlen_t pos = 0;
+	uint8_t byte;
+	*respos = 0;
+	*result = n;
+        if (!n) {
+		/** No root, no prefix found */
+		return 0;
+	}
+	/** For each node, look if we can make further progress */
+	while (n) {
+		if (pos == len) {
+			/** Exact match */
+			return 1;
+		}
+		byte = key[pos];
+		if (byte < n->offset) {
+			/** key < node */
+			return 1;
+		}
+		byte -= n->offset;
+		if (byte >= n->len) {
+			/** key > node */
+			return 1;
+		}
+		/** So far, the trie matches */
+		pos++;
+		if (n->array[byte].len != 0) {
+			/** Must match additional string */
+			if (pos + n->array[byte].len > len) {
+				return 1; /* no match at child node */
+			}
+			if (memcmp(&key[pos], n->array[byte].str,
+				n->array[byte].len) != 0) {
+				return 1; /* no match at child node */
+			}
+			pos += n->array[byte].len;
+		}
+		/** Continue searching prefix at this child node */
+		n = n->array[byte].edge;
+		if (!n) {
+			return 1;
+		}
+		/** Update the prefix node */
+		*respos = pos;
+		*result = n;
+	}
+	/** Done */
+	return 1;
+}
+
+
+/**
+ * Make space in the node's array for another byte.
+ * @param node: node.
+ * @param byte: byte.
+ * @return 1 if successful, 0 otherwise.
+ *
+ */
+static int
+ldns_radix_array_space(ldns_radix_node_t* node, uint8_t byte)
+{
+	/** Is there an array? */
+	if (!node->array) {
+		assert(node->capacity == 0);
+		/** No array, create new array */
+		node->array = LDNS_MALLOC(ldns_radix_array_t);
+		if (!node->array) {
+			return 0;
+		}
+		memset(&node->array[0], 0, sizeof(ldns_radix_array_t));
+		node->len = 1;
+		node->capacity = 1;
+		node->offset = byte;
+		return 1;
+	}
+	/** Array exist */
+	assert(node->array != NULL);
+	assert(node->capacity > 0);
+
+	if (node->len == 0) {
+		/** Unused array */
+		node->len = 1;
+		node->offset = byte;
+	} else if (byte < node->offset) {
+		/** Byte is below the offset */
+		uint8_t index;
+		uint16_t need = node->offset - byte;
+		/** Is there enough capacity? */
+		if (node->len + need > node->capacity) {
+			/** Not enough capacity, grow array */
+			if (!ldns_radix_array_grow(node,
+				(unsigned) (node->len + need))) {
+				return 0; /* failed to grow array */
+			}
+		}
+		/** Move items to the end */
+		memmove(&node->array[need], &node->array[0],
+			node->len*sizeof(ldns_radix_array_t));
+		/** Fix parent index */
+		for (index = 0; index < node->len; index++) {
+			if (node->array[index+need].edge) {
+				node->array[index+need].edge->parent_index =
+					index + need;
+			}
+		}
+		/** Zero the first */
+		memset(&node->array[0], 0, need*sizeof(ldns_radix_array_t));
+		node->len += need;
+		node->offset = byte;
+	} else if (byte - node->offset >= node->len) {
+		/** Byte does not fit in array */
+		uint16_t need = (byte - node->offset) - node->len + 1;
+		/** Is there enough capacity? */
+		if (node->len + need > node->capacity) {
+			/** Not enough capacity, grow array */
+			if (!ldns_radix_array_grow(node,
+				(unsigned) (node->len + need))) {
+				return 0; /* failed to grow array */
+			}
+		}
+		/** Zero the added items */
+		memset(&node->array[node->len], 0,
+			need*sizeof(ldns_radix_array_t));
+		node->len += need;
+	}
+	return 1;
+}
+
+
+/**
+ * Grow the array.
+ * @param node: node.
+ * @param need: number of elements the array at least need to grow.
+ *              Can't be bigger than 256.
+ * @return: 0 if failed, 1 if was successful.
+ *
+ */
+static int
+ldns_radix_array_grow(ldns_radix_node_t* node, unsigned need)
+{
+	unsigned size = ((unsigned)node->capacity)*2;
+	ldns_radix_array_t* a = NULL;
+	if (need > size) {
+		size = need;
+	}
+	if (size > 256) {
+		size = 256;
+	}
+	a = LDNS_XMALLOC(ldns_radix_array_t, size);
+	if (!a) {
+		return 0;
+	}
+	assert(node->len <= node->capacity);
+	assert(node->capacity < size);
+	memcpy(&a[0], &node->array[0], node->len*sizeof(ldns_radix_array_t));
+	LDNS_FREE(node->array);
+	node->array = a;
+	node->capacity = size;
+	return 1;
+}
+
+
+/**
+ * Create a prefix in the array string.
+ * @param array: array.
+ * @param key:   key.
+ * @param pos:   start position in key.
+ * @param len:   length of key.
+ * @return 0 if failed, 1 if was successful.
+ *
+ */
+static int
+ldns_radix_str_create(ldns_radix_array_t* array, uint8_t* key,
+	radix_strlen_t pos, radix_strlen_t len)
+{
+	array->str = LDNS_XMALLOC(uint8_t, (len-pos));
+	if (!array->str) {
+		return 0;
+	}
+	memmove(array->str, key+pos, len-pos);
+	array->len = (len-pos);
+	return 1;
+}
+
+
+/**
+ * Allocate remainder from prefixes for a split.
+ * @param prefixlen:  length of prefix.
+ * @param longer_str: the longer string.
+ * @param longer_len: the longer string length.
+ * @param split_str:  the split string.
+ * @param split_len:  the split string length.
+ * @return 0 if failed, 1 if successful.
+ *
+ */
+static int
+ldns_radix_prefix_remainder(radix_strlen_t prefix_len,
+	uint8_t* longer_str, radix_strlen_t longer_len,
+	uint8_t** split_str, radix_strlen_t* split_len)
+{
+	*split_len = longer_len - prefix_len;
+	*split_str = LDNS_XMALLOC(uint8_t, (*split_len));
+	if (!*split_str) {
+		return 0;
+	}
+	memmove(*split_str, longer_str+prefix_len, longer_len-prefix_len);
+	return 1;
+}
+
+
+/**
+ * Create a split when two nodes have a shared prefix.
+ * @param array: array.
+ * @param key:   key.
+ * @param pos:   start position in key.
+ * @param len:   length of the key.
+ * @param add:   node to be added.
+ * @return 0 if failed, 1 if was successful.
+ *
+ */
+static int
+ldns_radix_array_split(ldns_radix_array_t* array, uint8_t* key,
+	radix_strlen_t pos, radix_strlen_t len, ldns_radix_node_t* add)
+{
+	uint8_t* str_to_add = key + pos;
+	radix_strlen_t strlen_to_add = len - pos;
+
+	if (ldns_radix_str_is_prefix(str_to_add, strlen_to_add,
+		array->str, array->len)) {
+		/** The string to add is a prefix of the existing string */
+		uint8_t* split_str = NULL, *dup_str = NULL;
+		radix_strlen_t split_len = 0;
+		/**
+		 * Example 5: 'ld'
+		 * | [0]
+		 * --| [d+ns] dns
+		 * --| [e+dns] edns
+		 * --| [l+d] ld
+		 * ----| [n+s] ldns
+		 **/
+		assert(strlen_to_add < array->len);
+		/** Store the remainder in the split string */
+		if (array->len - strlen_to_add > 1) {
+			if (!ldns_radix_prefix_remainder(strlen_to_add+1,
+				array->str, array->len, &split_str,
+				&split_len)) {
+				return 0;
+			}
+		}
+		/** Duplicate the string to add */
+		if (strlen_to_add != 0) {
+			dup_str = LDNS_XMALLOC(uint8_t, strlen_to_add);
+			if (!dup_str) {
+				LDNS_FREE(split_str);
+				return 0;
+			}
+			memcpy(dup_str, str_to_add, strlen_to_add);
+		}
+		/** Make space in array for the new node */
+		if (!ldns_radix_array_space(add,
+			array->str[strlen_to_add])) {
+			LDNS_FREE(split_str);
+			LDNS_FREE(dup_str);
+			return 0;
+		}
+		/**
+		 * The added node should go direct under the existing parent.
+		 * The existing node should go under the added node.
+		 */
+		add->parent = array->edge->parent;
+		add->parent_index = array->edge->parent_index;
+		add->array[0].edge = array->edge;
+		add->array[0].str = split_str;
+		add->array[0].len = split_len;
+		array->edge->parent = add;
+		array->edge->parent_index = 0;
+		LDNS_FREE(array->str);
+		array->edge = add;
+		array->str = dup_str;
+		array->len = strlen_to_add;
+	} else if (ldns_radix_str_is_prefix(array->str, array->len,
+		str_to_add, strlen_to_add)) {
+		/** The existing string is a prefix of the string to add */
+		/**
+		 * Example 6: 'dns-ng'
+		 * | [0]
+		 * --| [d+ns] dns
+		 * ----| [-+ng] dns-ng
+		 * --| [e+dns] edns
+		 * --| [l+d] ld
+		 * ----| [n+s] ldns
+		 **/
+		uint8_t* split_str = NULL;
+		radix_strlen_t split_len = 0;
+		assert(array->len < strlen_to_add);
+		if (strlen_to_add - array->len > 1) {
+			if (!ldns_radix_prefix_remainder(array->len+1,
+				str_to_add, strlen_to_add, &split_str,
+				&split_len)) {
+				return 0;
+			}
+		}
+		/** Make space in array for the new node */
+		if (!ldns_radix_array_space(array->edge,
+			str_to_add[array->len])) {
+			LDNS_FREE(split_str);
+			return 0;
+		}
+		/**
+		 * The added node should go direct under the existing node.
+		 */
+		add->parent = array->edge;
+		add->parent_index = str_to_add[array->len] -
+							array->edge->offset;
+		array->edge->array[add->parent_index].edge = add;
+		array->edge->array[add->parent_index].str = split_str;
+		array->edge->array[add->parent_index].len = split_len;
+	} else {
+		/** Create a new split node. */
+		/**
+		 * Example 7: 'dndns'
+		 * | [0]
+		 * --| [d+n]
+		 * ----| [d+ns] dndns
+		 * ----| [s] dns
+		 * ------| [-+ng] dns-ng
+		 * --| [e+dns] edns
+		 * --| [l+d] ld
+		 * ----| [n+s] ldns
+		 **/
+		ldns_radix_node_t* common = NULL;
+		uint8_t* common_str = NULL, *s1 = NULL, *s2 = NULL;
+		radix_strlen_t common_len = 0, l1 = 0, l2 = 0;
+		common_len = ldns_radix_str_common(array->str, array->len,
+			str_to_add, strlen_to_add);
+		assert(common_len < array->len);
+		assert(common_len < strlen_to_add);
+		/** Create the new common node. */
+		common = ldns_radix_new_node(NULL, (uint8_t*)"", 0);
+		if (!common) {
+			return 0;
+		}
+		if (array->len - common_len > 1) {
+			if (!ldns_radix_prefix_remainder(common_len+1,
+				array->str, array->len, &s1, &l1)) {
+				return 0;
+			}
+		}
+		if (strlen_to_add - common_len > 1) {
+			if (!ldns_radix_prefix_remainder(common_len+1,
+				str_to_add, strlen_to_add, &s2, &l2)) {
+				return 0;
+			}
+		}
+		/** Create the shared prefix. */
+		if (common_len > 0) {
+			common_str = LDNS_XMALLOC(uint8_t, common_len);
+			if (!common_str) {
+				LDNS_FREE(common);
+				LDNS_FREE(s1);
+				LDNS_FREE(s2);
+				return 0;
+			}
+			memcpy(common_str, str_to_add, common_len);
+		}
+		/** Make space in the common node array. */
+		if (!ldns_radix_array_space(common, array->str[common_len]) ||
+		    !ldns_radix_array_space(common, str_to_add[common_len])) {
+			LDNS_FREE(common->array);
+			LDNS_FREE(common);
+			LDNS_FREE(common_str);
+			LDNS_FREE(s1);
+			LDNS_FREE(s2);
+			return 0;
+		}
+		/**
+		 * The common node should go direct under the parent node.
+		 * The added and existing nodes go under the common node.
+		 */
+		common->parent = array->edge->parent;
+		common->parent_index = array->edge->parent_index;
+		array->edge->parent = common;
+		array->edge->parent_index = array->str[common_len] -
+								common->offset;
+		add->parent = common;
+		add->parent_index = str_to_add[common_len] - common->offset;
+		common->array[array->edge->parent_index].edge = array->edge;
+		common->array[array->edge->parent_index].str = s1;
+		common->array[array->edge->parent_index].len = l1;
+		common->array[add->parent_index].edge = add;
+		common->array[add->parent_index].str = s2;
+		common->array[add->parent_index].len = l2;
+		LDNS_FREE(array->str);
+		array->edge = common;
+		array->str = common_str;
+		array->len = common_len;
+	}
+	return 1;
+}
+
+
+/**
+ * Check if one string prefix of other string.
+ * @param str1: one string.
+ * @param len1: one string length.
+ * @param str2: other string.
+ * @param len2: other string length.
+ * @return 1 if prefix, 0 otherwise.
+ *
+ */
+static int
+ldns_radix_str_is_prefix(uint8_t* str1, radix_strlen_t len1,
+	uint8_t* str2, radix_strlen_t len2)
+{
+	if (len1 == 0) {
+		return 1; /* empty prefix is also a prefix */
+	}
+	if (len1 > len2) {
+		return 0; /* len1 is longer so str1 cannot be a prefix */
+	}
+	return (memcmp(str1, str2, len1) == 0);
+}
+
+
+/**
+ * Return the number of bytes in common for the two strings.
+ * @param str1: one string.
+ * @param len1: one string length.
+ * @param str2: other string.
+ * @param len2: other string length.
+ * @return length of substring that the two strings have in common.
+ *
+ */
+static radix_strlen_t
+ldns_radix_str_common(uint8_t* str1, radix_strlen_t len1,
+	uint8_t* str2, radix_strlen_t len2)
+{
+	radix_strlen_t i, max = (len1<len2)?len1:len2;
+	for (i=0; i<max; i++) {
+		if (str1[i] != str2[i]) {
+			return i;
+		}
+	}
+	return max;
+}
+
+
+/**
+ * Find the next element in the subtree of this node.
+ * @param node: node.
+ * @return: node with next element.
+ *
+ */
+static ldns_radix_node_t*
+ldns_radix_next_in_subtree(ldns_radix_node_t* node)
+{
+	uint16_t i;
+	ldns_radix_node_t* next;
+	/** Try every subnode. */
+	for (i = 0; i < node->len; i++) {
+		if (node->array[i].edge) {
+			/** Node itself. */
+			if (node->array[i].edge->data) {
+				return node->array[i].edge;
+			}
+			/** Dive into subtree. */
+			next = ldns_radix_next_in_subtree(node->array[i].edge);
+			if (next) {
+				return next;
+			}
+		}
+	}
+	return NULL;
+}
+
+
+/**
+ * Find the previous element in the array of this node, from index.
+ * @param node: node.
+ * @param index: index.
+ * @return previous node from index.
+ *
+ */
+static ldns_radix_node_t*
+ldns_radix_prev_from_index(ldns_radix_node_t* node, uint8_t index)
+{
+	uint8_t i = index;
+	while (i > 0) {
+		i--;
+		if (node->array[i].edge) {
+			ldns_radix_node_t* prev =
+				ldns_radix_last_in_subtree_incl_self(node);
+			if (prev) {
+				return prev;
+			}
+		}
+	}
+	return NULL;
+}
+
+
+/**
+ * Find last node in subtree, or this node (if have data).
+ * @param node: node.
+ * @return last node in subtree, or this node, or NULL.
+ *
+ */
+static ldns_radix_node_t*
+ldns_radix_last_in_subtree_incl_self(ldns_radix_node_t* node)
+{
+	ldns_radix_node_t* last = ldns_radix_last_in_subtree(node);
+	if (last) {
+		return last;
+	} else if (node->data) {
+		return node;
+	}
+	return NULL;
+}
+
+
+/**
+ * Find last node in subtree.
+ * @param node: node.
+ * @return last node in subtree.
+ *
+ */
+static ldns_radix_node_t*
+ldns_radix_last_in_subtree(ldns_radix_node_t* node)
+{
+	int i;
+	/** Look for the most right leaf node. */
+	for (i=(int)(node->len)-1; i >= 0; i--) {
+		if (node->array[i].edge) {
+			/** Keep looking for the most right leaf node. */
+			if (node->array[i].edge->len > 0) {
+				ldns_radix_node_t* last =
+					ldns_radix_last_in_subtree(
+					node->array[i].edge);
+				if (last) {
+					return last;
+				}
+			}
+			/** Could this be the most right leaf node? */
+			if (node->array[i].edge->data) {
+				return node->array[i].edge;
+			}
+		}
+	}
+	return NULL;
+}
+
+
+/**
+ * Fix tree after deleting element.
+ * @param tree: tree.
+ * @param node: node with deleted element.
+ *
+ */
+static void
+ldns_radix_del_fix(ldns_radix_t* tree, ldns_radix_node_t* node)
+{
+	while (node) {
+		if (node->data) {
+			/** Thou should not delete nodes with data attached. */
+			return;
+		} else if (node->len == 1 && node->parent) {
+			/** Node with one child is fold back into. */
+			ldns_radix_cleanup_onechild(node);
+			return;
+		} else if (node->len == 0) {
+			/** Leaf node. */
+			ldns_radix_node_t* parent = node->parent;
+			if (!parent) {
+				/** The root is a leaf node. */
+				ldns_radix_node_free(node, NULL);
+				tree->root = NULL;
+				return;
+			}
+			/** Cleanup leaf node and continue with parent. */
+			ldns_radix_cleanup_leaf(node);
+			node = parent;
+		} else {
+			/**
+			 * Node cannot be deleted, because it has edge nodes
+			 * and no parent to fix up to.
+			 */
+			return;
+		}
+	}
+	/** Not reached. */
+	return;
+}
+
+
+/**
+ * Clean up a node with one child.
+ * @param node: node with one child.
+ *
+ */
+static void
+ldns_radix_cleanup_onechild(ldns_radix_node_t* node)
+{
+	uint8_t* join_str;
+	radix_strlen_t join_len;
+	uint8_t parent_index = node->parent_index;
+	ldns_radix_node_t* child = node->array[0].edge;
+	ldns_radix_node_t* parent = node->parent;
+
+	/** Node has one child, merge the child node into the parent node. */
+	assert(parent_index < parent->len);
+	join_len = parent->array[parent_index].len + node->array[0].len + 1;
+
+	join_str = LDNS_XMALLOC(uint8_t, join_len);
+	if (!join_str) {
+		/**
+		 * Cleanup failed due to out of memory.
+		 * This tree is now inefficient, with the empty node still
+		 * existing, but it is still valid.
+		 */
+		return;
+	}
+
+	memcpy(join_str, parent->array[parent_index].str,
+		parent->array[parent_index].len);
+	join_str[parent->array[parent_index].len] = child->parent_index +
+		node->offset;
+	memmove(join_str + parent->array[parent_index].len+1,
+		node->array[0].str, node->array[0].len);
+
+	LDNS_FREE(parent->array[parent_index].str);
+	parent->array[parent_index].str = join_str;
+	parent->array[parent_index].len = join_len;
+	parent->array[parent_index].edge = child;
+	child->parent = parent;
+	child->parent_index = parent_index;
+	ldns_radix_node_free(node, NULL);
+	return;
+}
+
+
+/**
+ * Clean up a leaf node.
+ * @param node: leaf node.
+ *
+ */
+static void
+ldns_radix_cleanup_leaf(ldns_radix_node_t* node)
+{
+	uint8_t parent_index = node->parent_index;
+	ldns_radix_node_t* parent = node->parent;
+	/** Delete lead node and fix parent array. */
+	assert(parent_index < parent->len);
+	ldns_radix_node_free(node, NULL);
+	LDNS_FREE(parent->array[parent_index].str);
+	parent->array[parent_index].str = NULL;
+	parent->array[parent_index].len = 0;
+	parent->array[parent_index].edge = NULL;
+	/** Fix array in parent. */
+	if (parent->len == 1) {
+		ldns_radix_node_array_free(parent);
+	} else if (parent_index == 0) {
+		ldns_radix_node_array_free_front(parent);
+	} else {
+		ldns_radix_node_array_free_end(parent);
+	}
+	return;
+}
+
+
+/**
+ * Free a radix node.
+ * @param node: node.
+ * @param arg: user argument.
+ *
+ */
+static void
+ldns_radix_node_free(ldns_radix_node_t* node, void* arg)
+{
+	uint16_t i;
+	(void) arg;
+	if (!node) {
+		return;
+	}
+	for (i=0; i < node->len; i++) {
+		LDNS_FREE(node->array[i].str);
+	}
+	node->key = NULL;
+	node->klen = 0;
+	LDNS_FREE(node->array);
+	LDNS_FREE(node);
+	return;
+}
+
+
+/**
+ * Free select edge array.
+ * @param node: node.
+ *
+ */
+static void
+ldns_radix_node_array_free(ldns_radix_node_t* node)
+{
+	node->offset = 0;
+	node->len = 0;
+	LDNS_FREE(node->array);
+	node->array = NULL;
+	node->capacity = 0;
+	return;
+}
+
+
+/**
+ * Free front of select edge array.
+ * @param node: node.
+ *
+ */
+static void
+ldns_radix_node_array_free_front(ldns_radix_node_t* node)
+{
+	uint16_t i, n = 0;
+	/** Remove until a non NULL entry. */
+   	while (n < node->len && node->array[n].edge == NULL) {
+		n++;
+	}
+	if (n == 0) {
+		return;
+	}
+	if (n == node->len) {
+		ldns_radix_node_array_free(node);
+		return;
+	}
+	assert(n < node->len);
+	assert((int) n <= (255 - (int) node->offset));
+	memmove(&node->array[0], &node->array[n],
+		(node->len - n)*sizeof(ldns_radix_array_t));
+	node->offset += n;
+	node->len -= n;
+	for (i=0; i < node->len; i++) {
+		if (node->array[i].edge) {
+			node->array[i].edge->parent_index = i;
+		}
+	}
+	ldns_radix_array_reduce(node);
+	return;
+}
+
+
+/**
+ * Free front of select edge array.
+ * @param node: node.
+ *
+ */
+static void
+ldns_radix_node_array_free_end(ldns_radix_node_t* node)
+{
+	uint16_t n = 0;
+	/** Shorten array. */
+	while (n < node->len && node->array[node->len-1-n].edge == NULL) {
+		n++;
+	}
+	if (n == 0) {
+		return;
+	}
+	if (n == node->len) {
+		ldns_radix_node_array_free(node);
+		return;
+	}
+	assert(n < node->len);
+	node->len -= n;
+	ldns_radix_array_reduce(node);
+	return;
+}
+
+
+/**
+ * Reduce the capacity of the array if needed.
+ * @param node: node.
+ *
+ */
+static void
+ldns_radix_array_reduce(ldns_radix_node_t* node)
+{
+	if (node->len <= node->capacity/2 && node->len != node->capacity) {
+		ldns_radix_array_t* a = LDNS_XMALLOC(ldns_radix_array_t,
+								node->len);
+		if (!a) {
+			return;
+		}
+		memcpy(a, node->array, sizeof(ldns_radix_array_t)*node->len);
+		LDNS_FREE(node->array);
+		node->array = a;
+		node->capacity = node->len;
+	}
+	return;
+}
+
+
+/**
+ * Return this element if it exists, the previous otherwise.
+ * @param node: from this node.
+ * @param result: result node.
+ *
+ */
+static void
+ldns_radix_self_or_prev(ldns_radix_node_t* node, ldns_radix_node_t** result)
+{
+	if (node->data) {
+		*result = node;
+	} else {
+		*result = ldns_radix_prev(node);
+	}
+	return;
+}
diff --git a/ldns/src/rbtree.c b/ldns/src/rbtree.c
new file mode 100644
index 0000000..b89dff7
--- /dev/null
+++ b/ldns/src/rbtree.c
@@ -0,0 +1,670 @@
+/*
+ * rbtree.c -- generic red black tree
+ *
+ * Taken from Unbound, modified for ldns
+ *
+ * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
+ * 
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * \file
+ * Implementation of a redblack tree.
+ */
+
+#include <ldns/config.h>
+#include <ldns/rbtree.h>
+#include <ldns/util.h>
+#include <stdlib.h>
+
+/** Node colour black */
+#define	BLACK	0
+/** Node colour red */
+#define	RED	1
+
+/** the NULL node, global alloc */
+ldns_rbnode_t	ldns_rbtree_null_node = {
+	LDNS_RBTREE_NULL,	/* Parent.  */
+	LDNS_RBTREE_NULL,	/* Left.  */
+	LDNS_RBTREE_NULL,	/* Right.  */
+	NULL,			/* Key.  */
+	NULL,               /* Data. */
+	BLACK		     /* Color.  */
+};
+
+/** rotate subtree left (to preserve redblack property) */
+static void ldns_rbtree_rotate_left(ldns_rbtree_t *rbtree, ldns_rbnode_t *node);
+/** rotate subtree right (to preserve redblack property) */
+static void ldns_rbtree_rotate_right(ldns_rbtree_t *rbtree, ldns_rbnode_t *node);
+/** Fixup node colours when insert happened */
+static void ldns_rbtree_insert_fixup(ldns_rbtree_t *rbtree, ldns_rbnode_t *node);
+/** Fixup node colours when delete happened */
+static void ldns_rbtree_delete_fixup(ldns_rbtree_t* rbtree, ldns_rbnode_t* child, ldns_rbnode_t* child_parent);
+
+/*
+ * Creates a new red black tree, intializes and returns a pointer to it.
+ *
+ * Return NULL on failure.
+ *
+ */
+ldns_rbtree_t *
+ldns_rbtree_create (int (*cmpf)(const void *, const void *))
+{
+	ldns_rbtree_t *rbtree;
+
+	/* Allocate memory for it */
+	rbtree = (ldns_rbtree_t *) LDNS_MALLOC(ldns_rbtree_t);
+	if (!rbtree) {
+		return NULL;
+	}
+
+	/* Initialize it */
+	ldns_rbtree_init(rbtree, cmpf);
+
+	return rbtree;
+}
+
+void 
+ldns_rbtree_init(ldns_rbtree_t *rbtree, int (*cmpf)(const void *, const void *))
+{
+	/* Initialize it */
+	rbtree->root = LDNS_RBTREE_NULL;
+	rbtree->count = 0;
+	rbtree->cmp = cmpf;
+}
+
+void 
+ldns_rbtree_free(ldns_rbtree_t *rbtree)
+{
+	LDNS_FREE(rbtree);
+}
+
+/*
+ * Rotates the node to the left.
+ *
+ */
+static void
+ldns_rbtree_rotate_left(ldns_rbtree_t *rbtree, ldns_rbnode_t *node)
+{
+	ldns_rbnode_t *right = node->right;
+	node->right = right->left;
+	if (right->left != LDNS_RBTREE_NULL)
+		right->left->parent = node;
+
+	right->parent = node->parent;
+
+	if (node->parent != LDNS_RBTREE_NULL) {
+		if (node == node->parent->left) {
+			node->parent->left = right;
+		} else  {
+			node->parent->right = right;
+		}
+	} else {
+		rbtree->root = right;
+	}
+	right->left = node;
+	node->parent = right;
+}
+
+/*
+ * Rotates the node to the right.
+ *
+ */
+static void
+ldns_rbtree_rotate_right(ldns_rbtree_t *rbtree, ldns_rbnode_t *node)
+{
+	ldns_rbnode_t *left = node->left;
+	node->left = left->right;
+	if (left->right != LDNS_RBTREE_NULL)
+		left->right->parent = node;
+
+	left->parent = node->parent;
+
+	if (node->parent != LDNS_RBTREE_NULL) {
+		if (node == node->parent->right) {
+			node->parent->right = left;
+		} else  {
+			node->parent->left = left;
+		}
+	} else {
+		rbtree->root = left;
+	}
+	left->right = node;
+	node->parent = left;
+}
+
+static void
+ldns_rbtree_insert_fixup(ldns_rbtree_t *rbtree, ldns_rbnode_t *node)
+{
+	ldns_rbnode_t	*uncle;
+
+	/* While not at the root and need fixing... */
+	while (node != rbtree->root && node->parent->color == RED) {
+		/* If our parent is left child of our grandparent... */
+		if (node->parent == node->parent->parent->left) {
+			uncle = node->parent->parent->right;
+
+			/* If our uncle is red... */
+			if (uncle->color == RED) {
+				/* Paint the parent and the uncle black... */
+				node->parent->color = BLACK;
+				uncle->color = BLACK;
+
+				/* And the grandparent red... */
+				node->parent->parent->color = RED;
+
+				/* And continue fixing the grandparent */
+				node = node->parent->parent;
+			} else {				/* Our uncle is black... */
+				/* Are we the right child? */
+				if (node == node->parent->right) {
+					node = node->parent;
+					ldns_rbtree_rotate_left(rbtree, node);
+				}
+				/* Now we're the left child, repaint and rotate... */
+				node->parent->color = BLACK;
+				node->parent->parent->color = RED;
+				ldns_rbtree_rotate_right(rbtree, node->parent->parent);
+			}
+		} else {
+			uncle = node->parent->parent->left;
+
+			/* If our uncle is red... */
+			if (uncle->color == RED) {
+				/* Paint the parent and the uncle black... */
+				node->parent->color = BLACK;
+				uncle->color = BLACK;
+
+				/* And the grandparent red... */
+				node->parent->parent->color = RED;
+
+				/* And continue fixing the grandparent */
+				node = node->parent->parent;
+			} else {				/* Our uncle is black... */
+				/* Are we the right child? */
+				if (node == node->parent->left) {
+					node = node->parent;
+					ldns_rbtree_rotate_right(rbtree, node);
+				}
+				/* Now we're the right child, repaint and rotate... */
+				node->parent->color = BLACK;
+				node->parent->parent->color = RED;
+				ldns_rbtree_rotate_left(rbtree, node->parent->parent);
+			}
+		}
+	}
+	rbtree->root->color = BLACK;
+}
+
+void
+ldns_rbtree_insert_vref(ldns_rbnode_t *data, void *rbtree)
+{
+	(void) ldns_rbtree_insert((ldns_rbtree_t *) rbtree,
+						 data);
+}
+
+/*
+ * Inserts a node into a red black tree.
+ *
+ * Returns NULL on failure or the pointer to the newly added node
+ * otherwise.
+ */
+ldns_rbnode_t *
+ldns_rbtree_insert (ldns_rbtree_t *rbtree, ldns_rbnode_t *data)
+{
+	/* XXX Not necessary, but keeps compiler quiet... */
+	int r = 0;
+
+	/* We start at the root of the tree */
+	ldns_rbnode_t	*node = rbtree->root;
+	ldns_rbnode_t	*parent = LDNS_RBTREE_NULL;
+
+	/* Lets find the new parent... */
+	while (node != LDNS_RBTREE_NULL) {
+		/* Compare two keys, do we have a duplicate? */
+		if ((r = rbtree->cmp(data->key, node->key)) == 0) {
+			return NULL;
+		}
+		parent = node;
+
+		if (r < 0) {
+			node = node->left;
+		} else {
+			node = node->right;
+		}
+	}
+
+	/* Initialize the new node */
+	data->parent = parent;
+	data->left = data->right = LDNS_RBTREE_NULL;
+	data->color = RED;
+	rbtree->count++;
+
+	/* Insert it into the tree... */
+	if (parent != LDNS_RBTREE_NULL) {
+		if (r < 0) {
+			parent->left = data;
+		} else {
+			parent->right = data;
+		}
+	} else {
+		rbtree->root = data;
+	}
+
+	/* Fix up the red-black properties... */
+	ldns_rbtree_insert_fixup(rbtree, data);
+
+	return data;
+}
+
+/*
+ * Searches the red black tree, returns the data if key is found or NULL otherwise.
+ *
+ */
+ldns_rbnode_t *
+ldns_rbtree_search (ldns_rbtree_t *rbtree, const void *key)
+{
+	ldns_rbnode_t *node;
+
+	if (ldns_rbtree_find_less_equal(rbtree, key, &node)) {
+		return node;
+	} else {
+		return NULL;
+	}
+}
+
+/** helpers for delete: swap node colours */
+static void swap_int8(uint8_t* x, uint8_t* y) 
+{ 
+	uint8_t t = *x; *x = *y; *y = t; 
+}
+
+/** helpers for delete: swap node pointers */
+static void swap_np(ldns_rbnode_t** x, ldns_rbnode_t** y) 
+{
+	ldns_rbnode_t* t = *x; *x = *y; *y = t; 
+}
+
+/** Update parent pointers of child trees of 'parent' */
+static void change_parent_ptr(ldns_rbtree_t* rbtree, ldns_rbnode_t* parent, ldns_rbnode_t* old, ldns_rbnode_t* new)
+{
+	if(parent == LDNS_RBTREE_NULL)
+	{
+		if(rbtree->root == old) rbtree->root = new;
+		return;
+	}
+	if(parent->left == old) parent->left = new;
+	if(parent->right == old) parent->right = new;
+}
+/** Update parent pointer of a node 'child' */
+static void change_child_ptr(ldns_rbnode_t* child, ldns_rbnode_t* old, ldns_rbnode_t* new)
+{
+	if(child == LDNS_RBTREE_NULL) return;
+	if(child->parent == old) child->parent = new;
+}
+
+ldns_rbnode_t* 
+ldns_rbtree_delete(ldns_rbtree_t *rbtree, const void *key)
+{
+	ldns_rbnode_t *to_delete;
+	ldns_rbnode_t *child;
+	if((to_delete = ldns_rbtree_search(rbtree, key)) == 0) return 0;
+	rbtree->count--;
+
+	/* make sure we have at most one non-leaf child */
+	if(to_delete->left != LDNS_RBTREE_NULL &&
+	   to_delete->right != LDNS_RBTREE_NULL)
+	{
+		/* swap with smallest from right subtree (or largest from left) */
+		ldns_rbnode_t *smright = to_delete->right;
+		while(smright->left != LDNS_RBTREE_NULL)
+			smright = smright->left;
+		/* swap the smright and to_delete elements in the tree,
+		 * but the ldns_rbnode_t is first part of user data struct
+		 * so cannot just swap the keys and data pointers. Instead
+		 * readjust the pointers left,right,parent */
+
+		/* swap colors - colors are tied to the position in the tree */
+		swap_int8(&to_delete->color, &smright->color);
+
+		/* swap child pointers in parents of smright/to_delete */
+		change_parent_ptr(rbtree, to_delete->parent, to_delete, smright);
+		if(to_delete->right != smright)
+			change_parent_ptr(rbtree, smright->parent, smright, to_delete);
+
+		/* swap parent pointers in children of smright/to_delete */
+		change_child_ptr(smright->left, smright, to_delete);
+		change_child_ptr(smright->left, smright, to_delete);
+		change_child_ptr(smright->right, smright, to_delete);
+		change_child_ptr(smright->right, smright, to_delete);
+		change_child_ptr(to_delete->left, to_delete, smright);
+		if(to_delete->right != smright)
+			change_child_ptr(to_delete->right, to_delete, smright);
+		if(to_delete->right == smright)
+		{
+			/* set up so after swap they work */
+			to_delete->right = to_delete;
+			smright->parent = smright;
+		}
+
+		/* swap pointers in to_delete/smright nodes */
+		swap_np(&to_delete->parent, &smright->parent);
+		swap_np(&to_delete->left, &smright->left);
+		swap_np(&to_delete->right, &smright->right);
+
+		/* now delete to_delete (which is at the location where the smright previously was) */
+	}
+
+	if(to_delete->left != LDNS_RBTREE_NULL) child = to_delete->left;
+	else child = to_delete->right;
+
+	/* unlink to_delete from the tree, replace to_delete with child */
+	change_parent_ptr(rbtree, to_delete->parent, to_delete, child);
+	change_child_ptr(child, to_delete, to_delete->parent);
+
+	if(to_delete->color == RED)
+	{
+		/* if node is red then the child (black) can be swapped in */
+	}
+	else if(child->color == RED)
+	{
+		/* change child to BLACK, removing a RED node is no problem */
+		if(child!=LDNS_RBTREE_NULL) child->color = BLACK;
+	}
+	else ldns_rbtree_delete_fixup(rbtree, child, to_delete->parent);
+
+	/* unlink completely */
+	to_delete->parent = LDNS_RBTREE_NULL;
+	to_delete->left = LDNS_RBTREE_NULL;
+	to_delete->right = LDNS_RBTREE_NULL;
+	to_delete->color = BLACK;
+	return to_delete;
+}
+
+static void ldns_rbtree_delete_fixup(ldns_rbtree_t* rbtree, ldns_rbnode_t* child, ldns_rbnode_t* child_parent)
+{
+	ldns_rbnode_t* sibling;
+	int go_up = 1;
+
+	/* determine sibling to the node that is one-black short */
+	if(child_parent->right == child) sibling = child_parent->left;
+	else sibling = child_parent->right;
+
+	while(go_up)
+	{
+		if(child_parent == LDNS_RBTREE_NULL)
+		{
+			/* removed parent==black from root, every path, so ok */
+			return;
+		}
+
+		if(sibling->color == RED)
+		{	/* rotate to get a black sibling */
+			child_parent->color = RED;
+			sibling->color = BLACK;
+			if(child_parent->right == child)
+				ldns_rbtree_rotate_right(rbtree, child_parent);
+			else	ldns_rbtree_rotate_left(rbtree, child_parent);
+			/* new sibling after rotation */
+			if(child_parent->right == child) sibling = child_parent->left;
+			else sibling = child_parent->right;
+		}
+
+		if(child_parent->color == BLACK 
+			&& sibling->color == BLACK
+			&& sibling->left->color == BLACK
+			&& sibling->right->color == BLACK)
+		{	/* fixup local with recolor of sibling */
+			if(sibling != LDNS_RBTREE_NULL)
+				sibling->color = RED;
+
+			child = child_parent;
+			child_parent = child_parent->parent;
+			/* prepare to go up, new sibling */
+			if(child_parent->right == child) sibling = child_parent->left;
+			else sibling = child_parent->right;
+		}
+		else go_up = 0;
+	}
+
+	if(child_parent->color == RED
+		&& sibling->color == BLACK
+		&& sibling->left->color == BLACK
+		&& sibling->right->color == BLACK) 
+	{
+		/* move red to sibling to rebalance */
+		if(sibling != LDNS_RBTREE_NULL)
+			sibling->color = RED;
+		child_parent->color = BLACK;
+		return;
+	}
+
+	/* get a new sibling, by rotating at sibling. See which child
+	   of sibling is red */
+	if(child_parent->right == child
+		&& sibling->color == BLACK
+		&& sibling->right->color == RED
+		&& sibling->left->color == BLACK)
+	{
+		sibling->color = RED;
+		sibling->right->color = BLACK;
+		ldns_rbtree_rotate_left(rbtree, sibling);
+		/* new sibling after rotation */
+		if(child_parent->right == child) sibling = child_parent->left;
+		else sibling = child_parent->right;
+	}
+	else if(child_parent->left == child
+		&& sibling->color == BLACK
+		&& sibling->left->color == RED
+		&& sibling->right->color == BLACK)
+	{
+		sibling->color = RED;
+		sibling->left->color = BLACK;
+		ldns_rbtree_rotate_right(rbtree, sibling);
+		/* new sibling after rotation */
+		if(child_parent->right == child) sibling = child_parent->left;
+		else sibling = child_parent->right;
+	}
+
+	/* now we have a black sibling with a red child. rotate and exchange colors. */
+	sibling->color = child_parent->color;
+	child_parent->color = BLACK;
+	if(child_parent->right == child)
+	{
+		sibling->left->color = BLACK;
+		ldns_rbtree_rotate_right(rbtree, child_parent);
+	}
+	else
+	{
+		sibling->right->color = BLACK;
+		ldns_rbtree_rotate_left(rbtree, child_parent);
+	}
+}
+
+int
+ldns_rbtree_find_less_equal(ldns_rbtree_t *rbtree, const void *key, ldns_rbnode_t **result)
+{
+	int r;
+	ldns_rbnode_t *node;
+
+	/* We start at root... */
+	node = rbtree->root;
+
+	*result = NULL;
+
+	/* While there are children... */
+	while (node != LDNS_RBTREE_NULL) {
+		r = rbtree->cmp(key, node->key);
+		if (r == 0) {
+			/* Exact match */
+			*result = node;
+			return 1;
+		} 
+		if (r < 0) {
+			node = node->left;
+		} else {
+			/* Temporary match */
+			*result = node;
+			node = node->right;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Finds the first element in the red black tree
+ *
+ */
+ldns_rbnode_t *
+ldns_rbtree_first (ldns_rbtree_t *rbtree)
+{
+	ldns_rbnode_t *node = rbtree->root;
+
+	if (rbtree->root != LDNS_RBTREE_NULL) {
+		for (node = rbtree->root; node->left != LDNS_RBTREE_NULL; node = node->left);
+	}
+	return node;
+}
+
+ldns_rbnode_t *
+ldns_rbtree_last (ldns_rbtree_t *rbtree)
+{
+	ldns_rbnode_t *node = rbtree->root;
+
+	if (rbtree->root != LDNS_RBTREE_NULL) {
+		for (node = rbtree->root; node->right != LDNS_RBTREE_NULL; node = node->right);
+	}
+	return node;
+}
+
+/*
+ * Returns the next node...
+ *
+ */
+ldns_rbnode_t *
+ldns_rbtree_next (ldns_rbnode_t *node)
+{
+	ldns_rbnode_t *parent;
+
+	if (node->right != LDNS_RBTREE_NULL) {
+		/* One right, then keep on going left... */
+		for (node = node->right;
+			node->left != LDNS_RBTREE_NULL;
+			node = node->left);
+	} else {
+		parent = node->parent;
+		while (parent != LDNS_RBTREE_NULL && node == parent->right) {
+			node = parent;
+			parent = parent->parent;
+		}
+		node = parent;
+	}
+	return node;
+}
+
+ldns_rbnode_t *
+ldns_rbtree_previous(ldns_rbnode_t *node)
+{
+	ldns_rbnode_t *parent;
+
+	if (node->left != LDNS_RBTREE_NULL) {
+		/* One left, then keep on going right... */
+		for (node = node->left;
+			node->right != LDNS_RBTREE_NULL;
+			node = node->right);
+	} else {
+		parent = node->parent;
+		while (parent != LDNS_RBTREE_NULL && node == parent->left) {
+			node = parent;
+			parent = parent->parent;
+		}
+		node = parent;
+	}
+	return node;
+}
+
+/**
+ * split off elements number of elements from the start
+ * of the name tree and return a new tree 
+ */
+ldns_rbtree_t *
+ldns_rbtree_split(ldns_rbtree_t *tree,
+			   size_t elements)
+{
+	ldns_rbtree_t *new_tree;
+	ldns_rbnode_t *cur_node;
+	ldns_rbnode_t *move_node;
+	size_t count = 0;
+
+	new_tree = ldns_rbtree_create(tree->cmp);
+
+	cur_node = ldns_rbtree_first(tree);
+	while (count < elements && cur_node != LDNS_RBTREE_NULL) {
+		move_node = ldns_rbtree_delete(tree, cur_node->key);
+		(void)ldns_rbtree_insert(new_tree, move_node);
+		cur_node = ldns_rbtree_first(tree);
+		count++;
+	}
+
+	return new_tree;
+}
+
+/*
+ * add all node from the second tree to the first (removing them from the
+ * second), and fix up nsec(3)s if present
+ */
+void
+ldns_rbtree_join(ldns_rbtree_t *tree1, ldns_rbtree_t *tree2)
+{
+	ldns_traverse_postorder(tree2, ldns_rbtree_insert_vref, tree1);
+}
+
+/** recursive descent traverse */
+static void 
+traverse_post(void (*func)(ldns_rbnode_t*, void*), void* arg, 
+	ldns_rbnode_t* node)
+{
+	if(!node || node == LDNS_RBTREE_NULL)
+		return;
+	/* recurse */
+	traverse_post(func, arg, node->left);
+	traverse_post(func, arg, node->right);
+	/* call user func */
+	(*func)(node, arg);
+}
+
+void 
+ldns_traverse_postorder(ldns_rbtree_t* tree, 
+	void (*func)(ldns_rbnode_t*, void*), void* arg)
+{
+	traverse_post(func, arg, tree->root);
+}
diff --git a/ldns/src/rdata.c b/ldns/src/rdata.c
new file mode 100644
index 0000000..6eb0096
--- /dev/null
+++ b/ldns/src/rdata.c
@@ -0,0 +1,757 @@
+/*
+ * rdata.c
+ *
+ * rdata implementation
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+/*
+ * Access functions 
+ * do this as functions to get type checking
+ */
+
+/* read */
+size_t
+ldns_rdf_size(const ldns_rdf *rd)
+{
+	assert(rd != NULL);
+	return rd->_size;
+}
+
+ldns_rdf_type
+ldns_rdf_get_type(const ldns_rdf *rd)
+{
+	assert(rd != NULL);
+	return rd->_type;
+}
+
+uint8_t *
+ldns_rdf_data(const ldns_rdf *rd)
+{
+	assert(rd != NULL);
+	return rd->_data;
+}
+
+/* write */
+void
+ldns_rdf_set_size(ldns_rdf *rd, size_t size)
+{
+	assert(rd != NULL);
+	rd->_size = size;
+}
+
+void
+ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type)
+{
+	assert(rd != NULL);
+	rd->_type = type;
+}
+
+void
+ldns_rdf_set_data(ldns_rdf *rd, void *data)
+{
+	/* only copy the pointer */
+	assert(rd != NULL);
+	rd->_data = data;
+}
+
+/* for types that allow it, return
+ * the native/host order type */
+uint8_t
+ldns_rdf2native_int8(const ldns_rdf *rd)
+{
+	uint8_t data;
+
+	/* only allow 8 bit rdfs */
+	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_BYTE) {
+		return 0;
+	}
+	
+	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
+	return data;
+}
+
+uint16_t
+ldns_rdf2native_int16(const ldns_rdf *rd)
+{
+	uint16_t data;
+
+	/* only allow 16 bit rdfs */
+	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_WORD) {
+		return 0;
+	}
+	
+	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
+	return ntohs(data);
+}
+
+uint32_t
+ldns_rdf2native_int32(const ldns_rdf *rd)
+{
+	uint32_t data;
+
+	/* only allow 32 bit rdfs */
+	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD) {
+		return 0;
+	}
+	
+	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
+	return ntohl(data);
+}
+
+time_t
+ldns_rdf2native_time_t(const ldns_rdf *rd)
+{
+	uint32_t data;
+
+	/* only allow 32 bit rdfs */
+	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD ||
+			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_TIME) {
+		return 0;
+	}
+	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
+	return (time_t)ntohl(data);
+}
+
+ldns_rdf *
+ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
+{
+	return ldns_rdf_new_frm_data(type, LDNS_RDF_SIZE_BYTE, &value);
+}
+
+ldns_rdf *
+ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
+{
+	uint16_t *rdf_data = LDNS_XMALLOC(uint16_t, 1);
+        ldns_rdf* rdf;
+	if (!rdf_data) {
+		return NULL;
+	}
+	ldns_write_uint16(rdf_data, value);
+	rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data);
+        if(!rdf)
+                LDNS_FREE(rdf_data);
+        return rdf;
+}
+
+ldns_rdf *
+ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
+{
+	uint32_t *rdf_data = LDNS_XMALLOC(uint32_t, 1);
+        ldns_rdf* rdf;
+	if (!rdf_data) {
+		return NULL;
+	}
+	ldns_write_uint32(rdf_data, value);
+	rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data);
+        if(!rdf)
+                LDNS_FREE(rdf_data);
+        return rdf;
+}
+
+ldns_rdf *
+ldns_native2rdf_int16_data(size_t size, uint8_t *data)
+{
+	uint8_t *rdf_data = LDNS_XMALLOC(uint8_t, size + 2);
+        ldns_rdf* rdf;
+	if (!rdf_data) {
+		return NULL;
+	}
+	ldns_write_uint16(rdf_data, size);
+	memcpy(rdf_data + 2, data, size);
+	rdf = ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data);
+        if(!rdf)
+                LDNS_FREE(rdf_data);
+        return rdf;
+}
+
+/* note: data must be allocated memory */
+ldns_rdf *
+ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
+{
+	ldns_rdf *rd;
+	rd = LDNS_MALLOC(ldns_rdf);
+	if (!rd) {
+		return NULL;
+	}
+	ldns_rdf_set_size(rd, size);
+	ldns_rdf_set_type(rd, type);
+	ldns_rdf_set_data(rd, data);
+	return rd;
+}
+
+ldns_rdf *
+ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
+{
+	ldns_rdf *rdf;
+
+	/* if the size is too big, fail */
+	if (size > LDNS_MAX_RDFLEN) {
+		return NULL;
+	}
+
+	/* allocate space */
+	rdf = LDNS_MALLOC(ldns_rdf);
+	if (!rdf) {
+		return NULL;
+	}
+	rdf->_data = LDNS_XMALLOC(uint8_t, size);
+	if (!rdf->_data) {
+		LDNS_FREE(rdf);
+		return NULL;
+	}
+	
+	/* set the values */
+	ldns_rdf_set_type(rdf, type);
+	ldns_rdf_set_size(rdf, size);
+	memcpy(rdf->_data, data, size);
+
+	return rdf;
+}
+
+ldns_rdf *
+ldns_rdf_clone(const ldns_rdf *rd)
+{
+	assert(rd != NULL);
+	return (ldns_rdf_new_frm_data( ldns_rdf_get_type(rd),
+		ldns_rdf_size(rd), ldns_rdf_data(rd)));
+}
+
+void
+ldns_rdf_deep_free(ldns_rdf *rd)
+{
+	if (rd) {
+		if (rd->_data) {
+			LDNS_FREE(rd->_data);
+		}
+		LDNS_FREE(rd);
+	}
+}
+
+void 
+ldns_rdf_free(ldns_rdf *rd)
+{
+	if (rd) {
+		LDNS_FREE(rd);
+	}
+}
+
+ldns_rdf *
+ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
+{
+	ldns_rdf *rdf = NULL;
+	ldns_status status;
+
+	switch (type) {
+	case LDNS_RDF_TYPE_DNAME:
+		status = ldns_str2rdf_dname(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_INT8:
+		status = ldns_str2rdf_int8(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_INT16:
+		status = ldns_str2rdf_int16(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_INT32:
+		status = ldns_str2rdf_int32(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_A:
+		status = ldns_str2rdf_a(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_AAAA:
+		status = ldns_str2rdf_aaaa(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_STR:
+		status = ldns_str2rdf_str(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_APL:
+		status = ldns_str2rdf_apl(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_B64:
+		status = ldns_str2rdf_b64(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_B32_EXT:
+		status = ldns_str2rdf_b32_ext(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_HEX:
+		status = ldns_str2rdf_hex(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_NSEC:
+		status = ldns_str2rdf_nsec(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_TYPE:
+		status = ldns_str2rdf_type(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_CLASS:
+		status = ldns_str2rdf_class(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_CERT_ALG:
+		status = ldns_str2rdf_cert_alg(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_ALG:
+		status = ldns_str2rdf_alg(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_UNKNOWN:
+		status = ldns_str2rdf_unknown(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_TIME:
+		status = ldns_str2rdf_time(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_PERIOD:
+		status = ldns_str2rdf_period(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_HIP:
+		status = ldns_str2rdf_hip(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_SERVICE:
+		status = ldns_str2rdf_service(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_LOC:
+		status = ldns_str2rdf_loc(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_WKS:
+		status = ldns_str2rdf_wks(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_NSAP:
+		status = ldns_str2rdf_nsap(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_ATMA:
+		status = ldns_str2rdf_atma(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_IPSECKEY:
+		status = ldns_str2rdf_ipseckey(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_NSEC3_SALT:
+		status = ldns_str2rdf_nsec3_salt(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
+		status = ldns_str2rdf_b32_ext(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_ILNP64:
+		status = ldns_str2rdf_ilnp64(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_EUI48:
+		status = ldns_str2rdf_eui48(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_EUI64:
+		status = ldns_str2rdf_eui64(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_TAG:
+		status = ldns_str2rdf_tag(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_LONG_STR:
+		status = ldns_str2rdf_long_str(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
+		status = ldns_str2rdf_certificate_usage(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_SELECTOR:
+		status = ldns_str2rdf_selector(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_MATCHING_TYPE:
+		status = ldns_str2rdf_matching_type(&rdf, str);
+		break;
+	case LDNS_RDF_TYPE_NONE:
+	default:
+		/* default default ??? */
+		status = LDNS_STATUS_ERR;
+		break;
+	}
+	if (LDNS_STATUS_OK == status) {
+		ldns_rdf_set_type(rdf, type);
+		return rdf;
+	}
+	if (rdf) {
+		LDNS_FREE(rdf);
+	}
+	return NULL;
+}
+
+ldns_status
+ldns_rdf_new_frm_fp(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp)
+{
+	return ldns_rdf_new_frm_fp_l(rdf, type, fp, NULL);
+}
+
+ldns_status
+ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr)
+{
+	char *line;
+	ldns_rdf *r;
+	ssize_t t;
+
+	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
+	if (!line) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	/* read an entire line in from the file */
+	if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) {
+		LDNS_FREE(line);
+		return LDNS_STATUS_SYNTAX_RDATA_ERR;
+	}
+	r =  ldns_rdf_new_frm_str(type, (const char*) line);
+	LDNS_FREE(line);
+	if (rdf) {
+		*rdf = r;
+		return LDNS_STATUS_OK;
+	} else {
+		return LDNS_STATUS_NULL;
+	}
+}
+
+ldns_rdf *
+ldns_rdf_address_reverse(ldns_rdf *rd)
+{
+	uint8_t buf_4[LDNS_IP4ADDRLEN];
+	uint8_t buf_6[LDNS_IP6ADDRLEN * 2];
+	ldns_rdf *rev;
+	ldns_rdf *in_addr;
+	ldns_rdf *ret_dname;
+	uint8_t octet;
+	uint8_t nnibble;
+	uint8_t nibble;
+	uint8_t i, j;
+
+	char *char_dname;
+	int nbit;
+
+	if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_A &&
+			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_AAAA) {
+		return NULL;
+	}
+
+	in_addr = NULL;
+	ret_dname = NULL;
+
+	switch(ldns_rdf_get_type(rd)) {
+		case LDNS_RDF_TYPE_A:
+			/* the length of the buffer is 4 */
+			buf_4[3] = ldns_rdf_data(rd)[0];
+			buf_4[2] = ldns_rdf_data(rd)[1];
+			buf_4[1] = ldns_rdf_data(rd)[2];
+			buf_4[0] = ldns_rdf_data(rd)[3];
+			in_addr = ldns_dname_new_frm_str("in-addr.arpa.");
+			if (!in_addr) {
+				return NULL;
+			}
+			/* make a new rdf and convert that back  */
+			rev = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_A,
+				LDNS_IP4ADDRLEN, (void*)&buf_4);
+			if (!rev) {
+				LDNS_FREE(in_addr);
+				return NULL;
+			}
+
+			/* convert rev to a string */
+			char_dname = ldns_rdf2str(rev);
+			if (!char_dname) {
+				LDNS_FREE(in_addr);
+				ldns_rdf_deep_free(rev);
+				return NULL;
+			}
+			/* transform back to rdf with type dname */
+			ret_dname = ldns_dname_new_frm_str(char_dname);
+			if (!ret_dname) {
+				LDNS_FREE(in_addr);
+				ldns_rdf_deep_free(rev);
+				LDNS_FREE(char_dname);
+				return NULL;
+			}
+			/* not needed anymore */
+			ldns_rdf_deep_free(rev);
+			LDNS_FREE(char_dname);
+			break;
+		case LDNS_RDF_TYPE_AAAA:
+			/* some foo magic to reverse the nibbles ... */
+
+			for (nbit = 127; nbit >= 0; nbit = nbit - 4) {
+				/* calculate octett (8 bit) */
+				octet = ( ((unsigned int) nbit) & 0x78) >> 3;
+				/* calculate nibble */
+				nnibble = ( ((unsigned int) nbit) & 0x04) >> 2;
+				/* extract nibble */
+				nibble = (ldns_rdf_data(rd)[octet] & ( 0xf << (4 * (1 -
+						 nnibble)) ) ) >> ( 4 * (1 - 
+						nnibble));
+
+				buf_6[(LDNS_IP6ADDRLEN * 2 - 1) -
+					(octet * 2 + nnibble)] = 
+						(uint8_t)ldns_int_to_hexdigit((int)nibble);
+			}
+
+			char_dname = LDNS_XMALLOC(char, (LDNS_IP6ADDRLEN * 4));
+			if (!char_dname) {
+				return NULL;
+			}
+			char_dname[LDNS_IP6ADDRLEN * 4 - 1] = '\0'; /* closure */
+
+			/* walk the string and add . 's */
+			for (i = 0, j = 0; i < LDNS_IP6ADDRLEN * 2; i++, j = j + 2) {
+				char_dname[j] = (char)buf_6[i];
+				if (i != LDNS_IP6ADDRLEN * 2 - 1) {
+					char_dname[j + 1] = '.';
+				}
+			}
+			in_addr = ldns_dname_new_frm_str("ip6.arpa.");
+			if (!in_addr) {
+				LDNS_FREE(char_dname);
+				return NULL;
+			}
+
+			/* convert rev to a string */
+			ret_dname = ldns_dname_new_frm_str(char_dname);
+			LDNS_FREE(char_dname);
+			if (!ret_dname) {
+				ldns_rdf_deep_free(in_addr);
+				return NULL;
+			}
+			break;
+		default:
+			break;
+	}
+	/* add the suffix */
+	rev = ldns_dname_cat_clone(ret_dname, in_addr);
+
+	ldns_rdf_deep_free(ret_dname);
+	ldns_rdf_deep_free(in_addr);
+	return rev;
+}
+
+ldns_status
+ldns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg,
+                            uint8_t *hit_size, uint8_t** hit,
+                            uint16_t *pk_size, uint8_t** pk)
+{
+	uint8_t *data;
+	size_t rdf_size;
+
+	if (! rdf || ! alg || ! hit || ! hit_size || ! pk || ! pk_size) {
+		return LDNS_STATUS_INVALID_POINTER;
+	} else if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_HIP) {
+		return LDNS_STATUS_INVALID_RDF_TYPE;
+	} else if ((rdf_size = ldns_rdf_size(rdf)) < 6) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	data = ldns_rdf_data(rdf);
+	*hit_size = data[0];
+	*alg      = data[1];
+	*pk_size  = ldns_read_uint16(data + 2);
+	*hit      = data + 4;
+	*pk       = data + 4 + *hit_size;
+	if (*hit_size == 0 || *pk_size == 0 ||
+			rdf_size < (size_t) *hit_size + *pk_size + 4) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf** rdf, uint8_t alg,
+                                uint8_t hit_size, uint8_t *hit,
+				uint16_t pk_size, uint8_t *pk)
+{
+	uint8_t *data;
+
+	if (! rdf) {
+		return LDNS_STATUS_INVALID_POINTER;
+	}
+	if (4 + hit_size + pk_size > LDNS_MAX_RDFLEN) {
+		return LDNS_STATUS_RDATA_OVERFLOW;
+	}
+	data = LDNS_XMALLOC(uint8_t, 4 + hit_size + pk_size);
+	if (data == NULL) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	data[0] = hit_size;
+	data[1] = alg;
+	ldns_write_uint16(data + 2, pk_size);
+	memcpy(data + 4, hit, hit_size);
+	memcpy(data + 4 + hit_size, pk, pk_size);
+	*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HIP, 4 + hit_size + pk_size, data);
+	if (! *rdf) {
+		LDNS_FREE(data);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_octet(char *word, size_t *length)
+{
+    char *s; 
+    char *p;
+    *length = 0;
+
+    for (s = p = word; *s != '\0'; s++,p++) {
+        switch (*s) {
+            case '.':
+                if (s[1] == '.') {
+		    return LDNS_STATUS_EMPTY_LABEL;
+                }
+                *p = *s;
+                (*length)++;
+                break;
+            case '\\':
+                if ('0' <= s[1] && s[1] <= '9' &&
+                    '0' <= s[2] && s[2] <= '9' &&
+                    '0' <= s[3] && s[3] <= '9') {
+                    /* \DDD seen */
+                    int val = ((s[1] - '0') * 100 +
+                           (s[2] - '0') * 10 + (s[3] - '0'));
+
+                    if (0 <= val && val <= 255) {
+                        /* this also handles \0 */
+                        s += 3;
+                        *p = val;
+                        (*length)++;
+                    } else {
+                        return LDNS_STATUS_DDD_OVERFLOW;
+                    }
+                } else {
+                    /* an espaced character, like \<space> ? 
+                    * remove the '\' keep the rest */
+                    *p = *++s;
+                    (*length)++;
+                }
+                break;
+            case '\"':
+                /* non quoted " Is either first or the last character in
+                 * the string */
+
+                *p = *++s; /* skip it */
+                (*length)++;
+		/* I'm not sure if this is needed in libdns... MG */
+                if ( *s == '\0' ) {
+                    /* ok, it was the last one */
+                    *p  = '\0'; 
+		    return LDNS_STATUS_OK;
+                }
+                break;
+            default:
+                *p = *s;
+                (*length)++;
+                break;
+        }
+    }
+    *p = '\0';
+    return LDNS_STATUS_OK;
+}
+
+int
+ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
+{
+	uint16_t i1, i2, i;
+	uint8_t *d1, *d2;
+
+	/* only when both are not NULL we can say anything about them */
+	if (!rd1 && !rd2) {
+		return 0;
+	}
+	if (!rd1 || !rd2) {
+		return -1;
+	}
+	i1 = ldns_rdf_size(rd1);
+	i2 = ldns_rdf_size(rd2);
+
+	if (i1 < i2) {
+		return -1;
+	} else if (i1 > i2) {
+		return +1;
+	} else {
+		d1 = (uint8_t*)ldns_rdf_data(rd1);
+		d2 = (uint8_t*)ldns_rdf_data(rd2);
+		for(i = 0; i < i1; i++) {
+			if (d1[i] < d2[i]) {
+				return -1;
+			} else if (d1[i] > d2[i]) {
+				return +1;
+			}
+		}
+	}
+	return 0;
+}
+
+uint32_t
+ldns_str2period(const char *nptr, const char **endptr)
+{
+	int sign = 0;
+	uint32_t i = 0;
+	uint32_t seconds = 0;
+
+	for(*endptr = nptr; **endptr; (*endptr)++) {
+		switch (**endptr) {
+			case ' ':
+			case '\t':
+				break;
+			case '-':
+				if(sign == 0) {
+					sign = -1;
+				} else {
+					return seconds;
+				}
+				break;
+			case '+':
+				if(sign == 0) {
+					sign = 1;
+				} else {
+					return seconds;
+				}
+				break;
+			case 's':
+			case 'S':
+				seconds += i;
+				i = 0;
+				break;
+			case 'm':
+			case 'M':
+				seconds += i * 60;
+				i = 0;
+				break;
+			case 'h':
+			case 'H':
+				seconds += i * 60 * 60;
+				i = 0;
+				break;
+			case 'd':
+			case 'D':
+				seconds += i * 60 * 60 * 24;
+				i = 0;
+				break;
+			case 'w':
+			case 'W':
+				seconds += i * 60 * 60 * 24 * 7;
+				i = 0;
+				break;
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				i *= 10;
+				i += (**endptr - '0');
+				break;
+			default:
+				seconds += i;
+				/* disregard signedness */
+				return seconds;
+		}
+	}
+	seconds += i;
+	/* disregard signedness */
+	return seconds;
+}
diff --git a/ldns/src/resolver.c b/ldns/src/resolver.c
new file mode 100644
index 0000000..b092404
--- /dev/null
+++ b/ldns/src/resolver.c
@@ -0,0 +1,1603 @@
+/*
+ * resolver.c
+ *
+ * resolver implementation
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+#include <strings.h>
+
+/* Access function for reading
+ * and setting the different Resolver
+ * options */
+
+/* read */
+uint16_t
+ldns_resolver_port(const ldns_resolver *r)
+{
+	return r->_port;
+}
+
+ldns_rdf *
+ldns_resolver_source(const ldns_resolver *r)
+{
+	return r->_source;
+}
+
+uint16_t
+ldns_resolver_edns_udp_size(const ldns_resolver *r)
+{
+	        return r->_edns_udp_size;
+}
+
+uint8_t
+ldns_resolver_retry(const ldns_resolver *r)
+{
+	return r->_retry;
+}
+
+uint8_t
+ldns_resolver_retrans(const ldns_resolver *r)
+{
+	return r->_retrans;
+}
+
+bool
+ldns_resolver_fallback(const ldns_resolver *r)
+{
+	return r->_fallback;
+}
+
+uint8_t
+ldns_resolver_ip6(const ldns_resolver *r)
+{
+	return r->_ip6;
+}
+
+bool
+ldns_resolver_recursive(const ldns_resolver *r)
+{
+	return r->_recursive;
+}
+
+bool
+ldns_resolver_debug(const ldns_resolver *r)
+{
+	return r->_debug;
+}
+
+bool
+ldns_resolver_dnsrch(const ldns_resolver *r)
+{
+	return r->_dnsrch;
+}
+
+bool
+ldns_resolver_fail(const ldns_resolver *r)
+{
+	return r->_fail;
+}
+
+bool
+ldns_resolver_defnames(const ldns_resolver *r)
+{
+	return r->_defnames;
+}
+
+ldns_rdf *
+ldns_resolver_domain(const ldns_resolver *r)
+{
+	return r->_domain;
+}
+
+ldns_rdf **
+ldns_resolver_searchlist(const ldns_resolver *r)
+{
+	return r->_searchlist;
+}
+
+ldns_rdf **
+ldns_resolver_nameservers(const ldns_resolver *r)
+{
+	return r->_nameservers;
+}
+
+size_t
+ldns_resolver_nameserver_count(const ldns_resolver *r)
+{
+	return r->_nameserver_count;
+}
+
+bool
+ldns_resolver_dnssec(const ldns_resolver *r)
+{
+	return r->_dnssec;
+}
+
+bool
+ldns_resolver_dnssec_cd(const ldns_resolver *r)
+{
+	return r->_dnssec_cd;
+}
+
+ldns_rr_list *
+ldns_resolver_dnssec_anchors(const ldns_resolver *r)
+{
+    return r->_dnssec_anchors;
+}
+
+bool
+ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys)
+{
+  size_t i;
+  bool result = false;
+
+  ldns_rr_list * trust_anchors;
+  ldns_rr * cur_rr;
+
+  if (!r || !keys) { return false; }
+
+  trust_anchors = ldns_resolver_dnssec_anchors(r);
+
+  if (!trust_anchors) { return false; }
+
+  for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
+
+    cur_rr = ldns_rr_list_rr(keys, i);
+    if (ldns_rr_list_contains_rr(trust_anchors, cur_rr)) {
+      if (trusted_keys) { ldns_rr_list_push_rr(trusted_keys, cur_rr); }
+      result = true;
+    }
+  }
+
+  return result;
+}
+
+bool
+ldns_resolver_igntc(const ldns_resolver *r)
+{
+	return r->_igntc;
+}
+
+bool
+ldns_resolver_usevc(const ldns_resolver *r)
+{
+	return r->_usevc;
+}
+
+size_t *
+ldns_resolver_rtt(const ldns_resolver *r)
+{
+	return r->_rtt;
+}
+
+size_t
+ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos)
+{
+	size_t *rtt;
+
+	assert(r != NULL);
+
+	rtt = ldns_resolver_rtt(r);
+
+	if (pos >= ldns_resolver_nameserver_count(r)) {
+		/* error ?*/
+		return 0;
+	} else {
+		return rtt[pos];
+	}
+
+}
+
+struct timeval
+ldns_resolver_timeout(const ldns_resolver *r)
+{
+	return r->_timeout;
+}
+
+char *
+ldns_resolver_tsig_keyname(const ldns_resolver *r)
+{
+	return r->_tsig_keyname;
+}
+
+char *
+ldns_resolver_tsig_algorithm(const ldns_resolver *r)
+{
+	return r->_tsig_algorithm;
+}
+
+char *
+ldns_resolver_tsig_keydata(const ldns_resolver *r)
+{
+	return r->_tsig_keydata;
+}
+
+bool
+ldns_resolver_random(const ldns_resolver *r)
+{
+	return r->_random;
+}
+
+size_t
+ldns_resolver_searchlist_count(const ldns_resolver *r)
+{
+	return r->_searchlist_count;
+}
+
+/* write */
+void
+ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
+{
+	r->_port = p;
+}
+
+void
+ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s)
+{
+	r->_source = s;
+}
+
+ldns_rdf *
+ldns_resolver_pop_nameserver(ldns_resolver *r)
+{
+	ldns_rdf **nameservers;
+	ldns_rdf *pop;
+	size_t ns_count;
+	size_t *rtt;
+
+	assert(r != NULL);
+
+	ns_count = ldns_resolver_nameserver_count(r);
+	nameservers = ldns_resolver_nameservers(r);
+	rtt = ldns_resolver_rtt(r);
+	if (ns_count == 0 || !nameservers) {
+		return NULL;
+	}
+
+	pop = nameservers[ns_count - 1];
+
+	if (ns_count == 1) {
+		LDNS_FREE(nameservers);
+		LDNS_FREE(rtt);
+
+		ldns_resolver_set_nameservers(r, NULL);
+		ldns_resolver_set_rtt(r, NULL);
+	} else {
+		nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, 
+				(ns_count - 1));
+		rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
+
+	        ldns_resolver_set_nameservers(r, nameservers);
+	        ldns_resolver_set_rtt(r, rtt);
+	}
+	/* decr the count */
+	ldns_resolver_dec_nameserver_count(r);
+	return pop;
+}
+
+ldns_status
+ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n)
+{
+	ldns_rdf **nameservers;
+	size_t ns_count;
+	size_t *rtt;
+
+	if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A &&
+			ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) {
+		return LDNS_STATUS_ERR;
+	}
+
+	ns_count = ldns_resolver_nameserver_count(r);
+	nameservers = ldns_resolver_nameservers(r);
+	rtt = ldns_resolver_rtt(r);
+
+	/* make room for the next one */
+	if (ns_count == 0) {
+		nameservers = LDNS_XMALLOC(ldns_rdf *, 1);
+	} else {
+		nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
+	}
+        if(!nameservers)
+                return LDNS_STATUS_MEM_ERR;
+
+	/* set the new value in the resolver */
+	ldns_resolver_set_nameservers(r, nameservers);
+
+	/* don't forget the rtt */
+	if (ns_count == 0) {
+		rtt = LDNS_XMALLOC(size_t, 1);
+	} else {
+		rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
+	}
+        if(!rtt)
+                return LDNS_STATUS_MEM_ERR;
+
+	/* slide n in its slot. */
+	/* we clone it here, because then we can free the original
+	 * rr's where it stood */
+	nameservers[ns_count] = ldns_rdf_clone(n);
+	rtt[ns_count] = LDNS_RESOLV_RTT_MIN;
+	ldns_resolver_incr_nameserver_count(r);
+	ldns_resolver_set_rtt(r, rtt);
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr)
+{
+	ldns_rdf *address;
+	if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
+			ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) {
+		return LDNS_STATUS_ERR;
+	}
+	address = ldns_rr_rdf(rr, 0); /* extract the ip number */
+	if (address) {
+		return ldns_resolver_push_nameserver(r, address);
+	} else {
+		return LDNS_STATUS_ERR;
+	}
+}
+
+ldns_status
+ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list *rrlist)
+{
+	ldns_rr *rr;
+	ldns_status stat;
+	size_t i;
+
+	stat = LDNS_STATUS_OK;
+	if (rrlist) {
+		for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
+			rr = ldns_rr_list_rr(rrlist, i);
+			if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) {
+				stat = LDNS_STATUS_ERR;
+				break;
+			}
+		}
+		return stat;
+	} else {
+		return LDNS_STATUS_ERR;
+	}
+}
+
+void
+ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
+{
+	        r->_edns_udp_size = s;
+}
+
+void
+ldns_resolver_set_recursive(ldns_resolver *r, bool re)
+{
+	r->_recursive = re;
+}
+
+void
+ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
+{
+	r->_dnssec = d;
+}
+
+void
+ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
+{
+	r->_dnssec_cd = d;
+}
+
+void
+ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
+{
+  r->_dnssec_anchors = l;
+}
+
+ldns_status
+ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
+{
+  ldns_rr_list * trust_anchors;
+
+  if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
+                ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS)) {
+
+    return LDNS_STATUS_ERR;
+  }
+
+  if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
+    trust_anchors = ldns_rr_list_new();
+    ldns_resolver_set_dnssec_anchors(r, trust_anchors);
+  }
+
+  return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
+}
+
+void
+ldns_resolver_set_igntc(ldns_resolver *r, bool i)
+{
+	r->_igntc = i;
+}
+
+void
+ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
+{
+	r->_usevc = vc;
+}
+
+void
+ldns_resolver_set_debug(ldns_resolver *r, bool d)
+{
+	r->_debug = d;
+}
+
+void
+ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
+{
+	r->_ip6 = ip6;
+}
+
+void
+ldns_resolver_set_fail(ldns_resolver *r, bool f)
+{
+	r->_fail =f;
+}
+
+static void
+ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
+{
+	r->_searchlist_count = c;
+}
+
+void
+ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
+{
+	r->_nameserver_count = c;
+}
+
+void
+ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
+{
+	r->_dnsrch = d;
+}
+
+void
+ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
+{
+	r->_retry = retry;
+}
+
+void
+ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
+{
+	r->_retrans = retrans;
+}
+
+void
+ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
+{
+	r->_fallback = fallback;
+}
+
+void
+ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
+{
+	r->_nameservers = n;
+}
+
+void
+ldns_resolver_set_defnames(ldns_resolver *r, bool d)
+{
+	r->_defnames = d;
+}
+
+void
+ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
+{
+	r->_rtt = rtt;
+}
+
+void
+ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
+{
+	size_t *rtt;
+
+	assert(r != NULL);
+
+	rtt = ldns_resolver_rtt(r);
+
+	if (pos >= ldns_resolver_nameserver_count(r)) {
+		/* error ?*/
+	} else {
+		rtt[pos] = value;
+	}
+
+}
+
+void
+ldns_resolver_incr_nameserver_count(ldns_resolver *r)
+{
+	size_t c;
+
+	c = ldns_resolver_nameserver_count(r);
+	ldns_resolver_set_nameserver_count(r, ++c);
+}
+
+void
+ldns_resolver_dec_nameserver_count(ldns_resolver *r)
+{
+	size_t c;
+
+	c = ldns_resolver_nameserver_count(r);
+	if (c == 0) {
+		return;
+	} else {
+		ldns_resolver_set_nameserver_count(r, --c);
+	}
+}
+
+void
+ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
+{
+	r->_domain = d;
+}
+
+void
+ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
+{
+	r->_timeout.tv_sec = timeout.tv_sec;
+	r->_timeout.tv_usec = timeout.tv_usec;
+}
+
+void
+ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
+{
+	ldns_rdf **searchlist;
+	size_t list_count;
+
+	if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
+		return;
+	}
+
+	list_count = ldns_resolver_searchlist_count(r);
+	searchlist = ldns_resolver_searchlist(r);
+
+	searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1));
+	if (searchlist) {
+		r->_searchlist = searchlist;
+
+		searchlist[list_count] = ldns_rdf_clone(d);
+		ldns_resolver_set_searchlist_count(r, list_count + 1);
+	} /* no way to report mem err */
+}
+
+void
+ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname)
+{
+	LDNS_FREE(r->_tsig_keyname);
+	r->_tsig_keyname = strdup(tsig_keyname);
+}
+
+void
+ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm)
+{
+	LDNS_FREE(r->_tsig_algorithm);
+	r->_tsig_algorithm = strdup(tsig_algorithm);
+}
+
+void
+ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata)
+{
+	LDNS_FREE(r->_tsig_keydata);
+	r->_tsig_keydata = strdup(tsig_keydata);
+}
+
+void
+ldns_resolver_set_random(ldns_resolver *r, bool b)
+{
+	r->_random = b;
+}
+
+/* more sophisticated functions */
+ldns_resolver *
+ldns_resolver_new(void)
+{
+	ldns_resolver *r;
+
+	r = LDNS_MALLOC(ldns_resolver);
+	if (!r) {
+		return NULL;
+	}
+
+	r->_searchlist = NULL;
+	r->_nameservers = NULL;
+	r->_rtt = NULL;
+
+	/* defaults are filled out */
+	ldns_resolver_set_searchlist_count(r, 0);
+	ldns_resolver_set_nameserver_count(r, 0);
+	ldns_resolver_set_usevc(r, 0);
+	ldns_resolver_set_port(r, LDNS_PORT);
+	ldns_resolver_set_domain(r, NULL);
+	ldns_resolver_set_defnames(r, false);
+	ldns_resolver_set_retry(r, 3);
+	ldns_resolver_set_retrans(r, 2);
+	ldns_resolver_set_fallback(r, true);
+	ldns_resolver_set_fail(r, false);
+	ldns_resolver_set_edns_udp_size(r, 0);
+	ldns_resolver_set_dnssec(r, false);
+	ldns_resolver_set_dnssec_cd(r, false);
+	ldns_resolver_set_dnssec_anchors(r, NULL);
+	ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
+	ldns_resolver_set_igntc(r, false);
+	ldns_resolver_set_recursive(r, false);
+	ldns_resolver_set_dnsrch(r, true);
+	ldns_resolver_set_source(r, NULL);
+	ldns_resolver_set_ixfr_serial(r, 0);
+
+	/* randomize the nameserver to be queried
+	 * when there are multiple
+	 */
+	ldns_resolver_set_random(r, true);
+
+	ldns_resolver_set_debug(r, 0);
+
+	r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
+	r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
+
+	/* TODO: fd=0 is actually a valid socket (stdin),
+           replace with -1 */
+	r->_socket = 0;
+	r->_axfr_soa_count = 0;
+	r->_axfr_i = 0;
+	r->_cur_axfr_pkt = NULL;
+
+	r->_tsig_keyname = NULL;
+	r->_tsig_keydata = NULL;
+	r->_tsig_algorithm = NULL;
+	return r;
+}
+
+ldns_resolver *
+ldns_resolver_clone(ldns_resolver *src)
+{
+	ldns_resolver *dst;
+	size_t i;
+
+	assert(src != NULL);
+
+	if (!(dst = LDNS_MALLOC(ldns_resolver))) return NULL;
+	(void) memcpy(dst, src, sizeof(ldns_resolver));
+
+	if (dst->_searchlist_count == 0)
+		dst->_searchlist = NULL;
+	else {
+		if (!(dst->_searchlist =
+		    LDNS_XMALLOC(ldns_rdf *, dst->_searchlist_count)))
+			goto error;
+		for (i = 0; i < dst->_searchlist_count; i++)
+			if (!(dst->_searchlist[i] =
+			    ldns_rdf_clone(src->_searchlist[i]))) {
+				dst->_searchlist_count = i;
+				goto error_searchlist;
+			}
+	}
+	if (dst->_nameserver_count == 0) {
+		dst->_nameservers = NULL;
+		dst->_rtt = NULL;
+	} else {
+		if (!(dst->_nameservers =
+		    LDNS_XMALLOC(ldns_rdf *, dst->_nameserver_count)))
+			goto error_searchlist;
+		for (i = 0; i < dst->_nameserver_count; i++)
+			if (!(dst->_nameservers[i] =
+			    ldns_rdf_clone(src->_nameservers[i]))) {
+				dst->_nameserver_count = i;
+				goto error_nameservers;
+			}
+		if (!(dst->_rtt =
+		    LDNS_XMALLOC(size_t, dst->_nameserver_count)))
+			goto error_nameservers;
+		(void) memcpy(dst->_rtt, src->_rtt,
+		    sizeof(size_t) * dst->_nameserver_count);
+	}
+	if (dst->_domain && (!(dst->_domain = ldns_rdf_clone(src->_domain))))
+		goto error_rtt;
+
+	if (dst->_tsig_keyname &&
+	    (!(dst->_tsig_keyname = strdup(src->_tsig_keyname))))
+		goto error_domain;
+
+	if (dst->_tsig_keydata &&
+	    (!(dst->_tsig_keydata = strdup(src->_tsig_keydata))))
+		goto error_tsig_keyname;
+
+	if (dst->_tsig_algorithm &&
+	    (!(dst->_tsig_algorithm = strdup(src->_tsig_algorithm))))
+		goto error_tsig_keydata;
+
+	if (dst->_cur_axfr_pkt &&
+	    (!(dst->_cur_axfr_pkt = ldns_pkt_clone(src->_cur_axfr_pkt))))
+		goto error_tsig_algorithm;
+
+	if (dst->_dnssec_anchors &&
+	    (!(dst->_dnssec_anchors=ldns_rr_list_clone(src->_dnssec_anchors))))
+		goto error_cur_axfr_pkt;
+
+	return dst;
+
+error_cur_axfr_pkt:
+	ldns_pkt_free(dst->_cur_axfr_pkt);
+error_tsig_algorithm:
+	LDNS_FREE(dst->_tsig_algorithm);
+error_tsig_keydata:
+	LDNS_FREE(dst->_tsig_keydata);
+error_tsig_keyname:
+	LDNS_FREE(dst->_tsig_keyname);
+error_domain:
+	ldns_rdf_deep_free(dst->_domain);
+error_rtt:
+	LDNS_FREE(dst->_rtt);
+error_nameservers:
+	for (i = 0; i < dst->_nameserver_count; i++)
+		ldns_rdf_deep_free(dst->_nameservers[i]);
+	LDNS_FREE(dst->_nameservers);
+error_searchlist:
+	for (i = 0; i < dst->_searchlist_count; i++)
+		ldns_rdf_deep_free(dst->_searchlist[i]);
+	LDNS_FREE(dst->_searchlist);
+error:
+	LDNS_FREE(dst);
+	return NULL;
+}
+
+
+ldns_status
+ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
+{
+	return ldns_resolver_new_frm_fp_l(res, fp, NULL);
+}
+
+ldns_status
+ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
+{
+	ldns_resolver *r;
+	const char *keyword[LDNS_RESOLV_KEYWORDS];
+	char word[LDNS_MAX_LINELEN + 1];
+	int8_t expect;
+	uint8_t i;
+	ldns_rdf *tmp;
+#ifdef HAVE_SSL
+	ldns_rr *tmp_rr;
+#endif
+	ssize_t gtr, bgtr;
+	ldns_buffer *b;
+        int lnr = 0, oldline;
+	FILE* myfp = fp;
+        if(!line_nr) line_nr = &lnr;
+
+	if(!fp) {
+		myfp = fopen("/etc/resolv.conf", "r");
+		if(!myfp)
+			return LDNS_STATUS_FILE_ERR;
+	}
+
+	/* do this better
+	 * expect =
+	 * 0: keyword
+	 * 1: default domain dname
+	 * 2: NS aaaa or a record
+	 */
+
+	/* recognized keywords */
+	keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
+	keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
+	keyword[LDNS_RESOLV_SEARCH] = "search";
+	/* these two are read but not used atm TODO */
+	keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
+	keyword[LDNS_RESOLV_OPTIONS] = "options";
+	keyword[LDNS_RESOLV_ANCHOR] = "anchor";
+	expect = LDNS_RESOLV_KEYWORD;
+
+	r = ldns_resolver_new();
+	if (!r) {
+		if(!fp) fclose(myfp);
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	gtr = 1;
+	word[0] = 0;
+        oldline = *line_nr;
+        expect = LDNS_RESOLV_KEYWORD;
+	while (gtr > 0) {
+		/* check comments */
+		if (word[0] == '#') {
+                        word[0]='x';
+                        if(oldline == *line_nr) {
+                                /* skip until end of line */
+                                int c;
+                                do {
+                                        c = fgetc(myfp);
+                                } while(c != EOF && c != '\n');
+                                if(c=='\n') (*line_nr)++;
+                        }
+			/* and read next to prepare for further parsing */
+                        oldline = *line_nr;
+			continue;
+		}
+                oldline = *line_nr;
+		switch(expect) {
+			case LDNS_RESOLV_KEYWORD:
+				/* keyword */
+				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
+				if (gtr != 0) {
+                                        if(word[0] == '#') continue;
+					for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
+						if (strcasecmp(keyword[i], word) == 0) {
+							/* chosen the keyword and
+							 * expect values carefully
+	        					 */
+							expect = i;
+							break;
+						}
+					}
+					/* no keyword recognized */
+					if (expect == LDNS_RESOLV_KEYWORD) {
+						/* skip line */
+						/*
+						ldns_resolver_deep_free(r);
+						if(!fp) fclose(myfp);
+						return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
+						*/
+					}
+				}
+				break;
+			case LDNS_RESOLV_DEFDOMAIN:
+				/* default domain dname */
+				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
+				if (gtr == 0) {
+					if(!fp) fclose(myfp);
+					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
+				}
+                                if(word[0] == '#') {
+                                        expect = LDNS_RESOLV_KEYWORD;
+                                        continue;
+                                }
+				tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
+				if (!tmp) {
+					ldns_resolver_deep_free(r);
+					if(!fp) fclose(myfp);
+					return LDNS_STATUS_SYNTAX_DNAME_ERR;
+				}
+
+				/* DOn't free, because we copy the pointer */
+				ldns_resolver_set_domain(r, tmp);
+				expect = LDNS_RESOLV_KEYWORD;
+				break;
+			case LDNS_RESOLV_NAMESERVER:
+				/* NS aaaa or a record */
+				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
+				if (gtr == 0) {
+					if(!fp) fclose(myfp);
+					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
+				}
+                                if(word[0] == '#') {
+                                        expect = LDNS_RESOLV_KEYWORD;
+                                        continue;
+                                }
+                                if(strchr(word, '%')) {
+                                        /* snip off interface labels,
+                                         * fe80::222:19ff:fe31:4222%eth0 */
+                                        strchr(word, '%')[0]=0;
+                                }
+				tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
+				if (!tmp) {
+					/* try ip4 */
+					tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
+				}
+				/* could not parse it, exit */
+				if (!tmp) {
+					ldns_resolver_deep_free(r);
+					if(!fp) fclose(myfp);
+					return LDNS_STATUS_SYNTAX_ERR;
+				}
+				(void)ldns_resolver_push_nameserver(r, tmp);
+				ldns_rdf_deep_free(tmp);
+				expect = LDNS_RESOLV_KEYWORD;
+				break;
+			case LDNS_RESOLV_SEARCH:
+				/* search list domain dname */
+				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
+				b = LDNS_MALLOC(ldns_buffer);
+				if(!b) {
+					ldns_resolver_deep_free(r);
+					if(!fp) fclose(myfp);
+					return LDNS_STATUS_MEM_ERR;
+				}
+
+				ldns_buffer_new_frm_data(b, word, (size_t) gtr);
+				if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
+					LDNS_FREE(b);
+					ldns_resolver_deep_free(r);
+					if(!fp) fclose(myfp);
+					return LDNS_STATUS_MEM_ERR;
+				}
+				bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
+				while (bgtr > 0) {
+					gtr -= bgtr;
+                                        if(word[0] == '#') {
+                                                expect = LDNS_RESOLV_KEYWORD;
+                                                break;
+                                        }
+					tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
+					if (!tmp) {
+						ldns_resolver_deep_free(r);
+						ldns_buffer_free(b);
+						if(!fp) fclose(myfp);
+						return LDNS_STATUS_SYNTAX_DNAME_ERR;
+					}
+
+					ldns_resolver_push_searchlist(r, tmp);
+
+					ldns_rdf_deep_free(tmp);
+					bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
+					    (size_t) gtr + 1);
+				}
+				ldns_buffer_free(b);
+				if (expect != LDNS_RESOLV_KEYWORD) {
+					gtr = 1;
+					expect = LDNS_RESOLV_KEYWORD;
+				}
+				break;
+			case LDNS_RESOLV_SORTLIST:
+				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
+				/* sortlist not implemented atm */
+				expect = LDNS_RESOLV_KEYWORD;
+				break;
+			case LDNS_RESOLV_OPTIONS:
+				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
+				/* options not implemented atm */
+				expect = LDNS_RESOLV_KEYWORD;
+				break;
+			case LDNS_RESOLV_ANCHOR:
+				/* a file containing a DNSSEC trust anchor */
+				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
+				if (gtr == 0) {
+					ldns_resolver_deep_free(r);
+					if(!fp) fclose(myfp);
+					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
+				}
+                                if(word[0] == '#') {
+                                        expect = LDNS_RESOLV_KEYWORD;
+                                        continue;
+                                }
+
+#ifdef HAVE_SSL
+				tmp_rr = ldns_read_anchor_file(word);
+				(void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
+				ldns_rr_free(tmp_rr);
+#endif
+				expect = LDNS_RESOLV_KEYWORD;
+				break;
+		}
+	}
+
+	if(!fp)
+		fclose(myfp);
+
+	if (res) {
+		*res = r;
+		return LDNS_STATUS_OK;
+	} else {
+		ldns_resolver_deep_free(r);
+		return LDNS_STATUS_NULL;
+	}
+}
+
+ldns_status
+ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
+{
+	ldns_resolver *r;
+	FILE *fp;
+	ldns_status s;
+
+	if (!filename) {
+		fp = fopen(LDNS_RESOLV_CONF, "r");
+
+	} else {
+		fp = fopen(filename, "r");
+	}
+	if (!fp) {
+		return LDNS_STATUS_FILE_ERR;
+	}
+
+	s = ldns_resolver_new_frm_fp(&r, fp);
+	fclose(fp);
+	if (s == LDNS_STATUS_OK) {
+		if (res) {
+			*res = r;
+			return LDNS_STATUS_OK;
+		} else  {
+			ldns_resolver_free(r);
+			return LDNS_STATUS_NULL;
+		}
+	}
+	return s;
+}
+
+void
+ldns_resolver_free(ldns_resolver *res)
+{
+	LDNS_FREE(res);
+}
+
+void
+ldns_resolver_deep_free(ldns_resolver *res)
+{
+	size_t i;
+
+	if (res) {
+		if (res->_searchlist) {
+			for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
+				ldns_rdf_deep_free(res->_searchlist[i]);
+			}
+			LDNS_FREE(res->_searchlist);
+		}
+		if (res->_nameservers) {
+			for (i = 0; i < res->_nameserver_count; i++) {
+				ldns_rdf_deep_free(res->_nameservers[i]);
+			}
+			LDNS_FREE(res->_nameservers);
+		}
+		if (ldns_resolver_domain(res)) {
+			ldns_rdf_deep_free(ldns_resolver_domain(res));
+		}
+		if (res->_tsig_keyname) {
+			LDNS_FREE(res->_tsig_keyname);
+		}
+		if (res->_tsig_keydata) {
+			LDNS_FREE(res->_tsig_keydata);
+		}
+		if (res->_tsig_algorithm) {
+			LDNS_FREE(res->_tsig_algorithm);
+		}
+
+		if (res->_cur_axfr_pkt) {
+			ldns_pkt_free(res->_cur_axfr_pkt);
+		}
+
+		if (res->_rtt) {
+			LDNS_FREE(res->_rtt);
+		}
+		if (res->_dnssec_anchors) {
+			ldns_rr_list_deep_free(res->_dnssec_anchors);
+		}
+		LDNS_FREE(res);
+	}
+}
+
+ldns_status
+ldns_resolver_search_status(ldns_pkt** pkt,
+		ldns_resolver *r, const  ldns_rdf *name,
+		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
+{
+	ldns_rdf *new_name;
+	ldns_rdf **search_list;
+	size_t i;
+	ldns_status s = LDNS_STATUS_OK;
+	ldns_rdf root_dname = { 1, LDNS_RDF_TYPE_DNAME, (void *)"" };
+
+	if (ldns_dname_absolute(name)) {
+		/* query as-is */
+		return ldns_resolver_query_status(pkt, r, name, t, c, flags);
+	} else if (ldns_resolver_dnsrch(r)) {
+		search_list = ldns_resolver_searchlist(r);
+		for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) {
+			if (i == ldns_resolver_searchlist_count(r)) {
+				new_name = ldns_dname_cat_clone(name,
+						&root_dname);
+			} else {
+				new_name = ldns_dname_cat_clone(name,
+						search_list[i]);
+			}
+
+			s = ldns_resolver_query_status(pkt, r,
+					new_name, t, c, flags);
+			ldns_rdf_free(new_name);
+			if (pkt && *pkt) {
+				if (s == LDNS_STATUS_OK && 
+						ldns_pkt_get_rcode(*pkt) ==
+						LDNS_RCODE_NOERROR) {
+
+					return LDNS_STATUS_OK;
+				}
+				ldns_pkt_free(*pkt);
+				*pkt = NULL;
+			}
+		}
+	}
+	return s;
+}
+
+ldns_pkt *
+ldns_resolver_search(const ldns_resolver *r,const  ldns_rdf *name,
+	ldns_rr_type t, ldns_rr_class c, uint16_t flags)
+{
+	ldns_pkt* pkt = NULL;
+	if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r,
+				name, t, c, flags) != LDNS_STATUS_OK) {
+		ldns_pkt_free(pkt);
+	}
+	return pkt;
+}
+
+ldns_status
+ldns_resolver_query_status(ldns_pkt** pkt,
+		ldns_resolver *r, const ldns_rdf *name,
+		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
+{
+	ldns_rdf *newname;
+	ldns_status status;
+
+	if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) {
+		return ldns_resolver_send(pkt, r, name, t, c, flags);
+	}
+
+	newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r));
+	if (!newname) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	status = ldns_resolver_send(pkt, r, newname, t, c, flags);
+	ldns_rdf_free(newname);
+	return status;
+}
+
+ldns_pkt *
+ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
+	ldns_rr_type t, ldns_rr_class c, uint16_t flags)
+{
+	ldns_pkt* pkt = NULL;
+	if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r,
+				name, t, c, flags) != LDNS_STATUS_OK) {
+		ldns_pkt_free(pkt);
+	}
+	return pkt;
+}
+
+static size_t *
+ldns_resolver_backup_rtt(ldns_resolver *r)
+{
+	size_t *new_rtt;
+	size_t *old_rtt = ldns_resolver_rtt(r);
+
+	if (old_rtt && ldns_resolver_nameserver_count(r)) {
+		new_rtt = LDNS_XMALLOC(size_t
+				, ldns_resolver_nameserver_count(r));
+		memcpy(new_rtt, old_rtt, sizeof(size_t)
+				* ldns_resolver_nameserver_count(r));
+		ldns_resolver_set_rtt(r, new_rtt);
+		return old_rtt;
+	}
+	return NULL;
+}
+
+static void
+ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
+{
+	size_t *cur_rtt = ldns_resolver_rtt(r);
+
+	if (cur_rtt) {
+		LDNS_FREE(cur_rtt);
+	}
+	ldns_resolver_set_rtt(r, old_rtt);
+}
+
+ldns_status
+ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
+				   ldns_pkt *query_pkt)
+{
+	ldns_pkt *answer_pkt = NULL;
+	ldns_status stat = LDNS_STATUS_OK;
+	size_t *rtt;
+
+	stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
+	if (stat != LDNS_STATUS_OK) {
+		if(answer_pkt) {
+			ldns_pkt_free(answer_pkt);
+			answer_pkt = NULL;
+		}
+	} else {
+		/* if tc=1 fall back to EDNS and/or TCP */
+		/* check for tcp first (otherwise we don't care about tc=1) */
+		if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
+			if (ldns_pkt_tc(answer_pkt)) {
+				/* was EDNS0 set? */
+				if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
+					ldns_pkt_set_edns_udp_size(query_pkt
+							, 4096);
+					ldns_pkt_free(answer_pkt);
+					answer_pkt = NULL;
+					/* Nameservers should not become 
+					 * unreachable because fragments are
+					 * dropped (network error). We might
+					 * still have success with TCP.
+					 * Therefore maintain reachability
+					 * statuses of the nameservers by
+					 * backup and restore the rtt list.
+					 */
+					rtt = ldns_resolver_backup_rtt(r);
+					stat = ldns_send(&answer_pkt, r
+							, query_pkt);
+					ldns_resolver_restore_rtt(r, rtt);
+				}
+				/* either way, if it is still truncated, use TCP */
+				if (stat != LDNS_STATUS_OK ||
+				    ldns_pkt_tc(answer_pkt)) {
+					ldns_resolver_set_usevc(r, true);
+					ldns_pkt_free(answer_pkt);
+					stat = ldns_send(&answer_pkt, r, query_pkt);
+					ldns_resolver_set_usevc(r, false);
+				}
+			}
+		}
+	}
+
+	if (answer) {
+		*answer = answer_pkt;
+	}
+
+	return stat;
+}
+
+ldns_status
+ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r,
+                                const ldns_rdf *name, ldns_rr_type t,
+                                ldns_rr_class c, uint16_t flags)
+{
+	struct timeval now;
+	ldns_rr* soa = NULL;
+
+	/* prepare a question pkt from the parameters
+	 * and then send this */
+	if (t == LDNS_RR_TYPE_IXFR) {
+		ldns_rdf *owner_rdf;
+		ldns_rdf *mname_rdf;
+		ldns_rdf *rname_rdf;
+		ldns_rdf *serial_rdf;
+		ldns_rdf *refresh_rdf;
+		ldns_rdf *retry_rdf;
+		ldns_rdf *expire_rdf;
+		ldns_rdf *minimum_rdf;
+		soa = ldns_rr_new();
+
+		if (!soa) {
+			return LDNS_STATUS_ERR;
+		}
+		owner_rdf = ldns_rdf_clone(name);
+		if (!owner_rdf) {
+			ldns_rr_free(soa);
+			return LDNS_STATUS_ERR;
+		}
+		ldns_rr_set_owner(soa, owner_rdf);
+		ldns_rr_set_type(soa, LDNS_RR_TYPE_SOA);
+		ldns_rr_set_class(soa, c);
+		ldns_rr_set_question(soa, false);
+		if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
+			ldns_rr_free(soa);
+			return LDNS_STATUS_ERR;
+		} else	ldns_rr_push_rdf(soa, mname_rdf);
+		if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
+			ldns_rr_free(soa);
+			return LDNS_STATUS_ERR;
+		} else	ldns_rr_push_rdf(soa, rname_rdf);
+		serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, ldns_resolver_get_ixfr_serial(r));
+		if (!serial_rdf) {
+			ldns_rr_free(soa);
+			return LDNS_STATUS_ERR;
+		} else	ldns_rr_push_rdf(soa, serial_rdf);
+		refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+		if (!refresh_rdf) {
+			ldns_rr_free(soa);
+			return LDNS_STATUS_ERR;
+		} else	ldns_rr_push_rdf(soa, refresh_rdf);
+		retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+		if (!retry_rdf) {
+			ldns_rr_free(soa);
+			return LDNS_STATUS_ERR;
+		} else	ldns_rr_push_rdf(soa, retry_rdf);
+		expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+		if (!expire_rdf) {
+			ldns_rr_free(soa);
+			return LDNS_STATUS_ERR;
+		} else	ldns_rr_push_rdf(soa, expire_rdf);
+		minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
+		if (!minimum_rdf) {
+			ldns_rr_free(soa);
+			return LDNS_STATUS_ERR;
+		} else	ldns_rr_push_rdf(soa, minimum_rdf);
+
+		*query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name),
+			c, flags, soa);
+	} else {
+		*query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
+	}
+	if (!*query_pkt) {
+		ldns_rr_free(soa);
+		return LDNS_STATUS_ERR;
+	}
+
+	/* set DO bit if necessary */
+	if (ldns_resolver_dnssec(r)) {
+		if (ldns_resolver_edns_udp_size(r) == 0) {
+			ldns_resolver_set_edns_udp_size(r, 4096);
+		}
+		ldns_pkt_set_edns_do(*query_pkt, true);
+		if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
+			ldns_pkt_set_cd(*query_pkt, true);
+		}
+	}
+
+	/* transfer the udp_edns_size from the resolver to the packet */
+	if (ldns_resolver_edns_udp_size(r) != 0) {
+		ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r));
+	}
+
+	/* set the timestamp */
+	now.tv_sec = time(NULL);
+	now.tv_usec = 0;
+	ldns_pkt_set_timestamp(*query_pkt, now);
+
+
+	if (ldns_resolver_debug(r)) {
+		ldns_pkt_print(stdout, *query_pkt);
+	}
+
+	/* only set the id if it is not set yet */
+	if (ldns_pkt_id(*query_pkt) == 0) {
+		ldns_pkt_set_random_id(*query_pkt);
+	}
+
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
+		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
+{
+	ldns_pkt *query_pkt;
+	ldns_pkt *answer_pkt;
+	ldns_status status;
+
+	assert(r != NULL);
+	assert(name != NULL);
+
+	answer_pkt = NULL;
+
+	/* do all the preprocessing here, then fire of an query to
+	 * the network */
+
+	if (0 == t) {
+		t= LDNS_RR_TYPE_A;
+	}
+	if (0 == c) {
+		c= LDNS_RR_CLASS_IN;
+	}
+	if (0 == ldns_resolver_nameserver_count(r)) {
+		return LDNS_STATUS_RES_NO_NS;
+	}
+	if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
+		return LDNS_STATUS_RES_QUERY;
+	}
+
+	status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
+	                                         t, c, flags);
+	if (status != LDNS_STATUS_OK) {
+		return status;
+	}
+
+	/* if tsig values are set, tsign it */
+	/* TODO: make last 3 arguments optional too? maybe make complete
+	         rr instead of separate values in resolver (and packet)
+	  Jelte
+	  should this go in pkt_prepare?
+	*/
+	if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) {
+#ifdef HAVE_SSL
+		status = ldns_pkt_tsig_sign(query_pkt,
+		                            ldns_resolver_tsig_keyname(r),
+		                            ldns_resolver_tsig_keydata(r),
+		                            300, ldns_resolver_tsig_algorithm(r), NULL);
+		if (status != LDNS_STATUS_OK) {
+			ldns_pkt_free(query_pkt);
+			return LDNS_STATUS_CRYPTO_TSIG_ERR;
+		}
+#else
+		ldns_pkt_free(query_pkt);
+	        return LDNS_STATUS_CRYPTO_TSIG_ERR;
+#endif /* HAVE_SSL */
+	}
+
+	status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
+	ldns_pkt_free(query_pkt);
+
+	/* allows answer to be NULL when not interested in return value */
+	if (answer) {
+		*answer = answer_pkt;
+	}
+	return status;
+}
+
+ldns_rr *
+ldns_axfr_next(ldns_resolver *resolver)
+{
+	ldns_rr *cur_rr;
+	uint8_t *packet_wire;
+	size_t packet_wire_size;
+	ldns_status status;
+
+	/* check if start() has been called */
+	if (!resolver || resolver->_socket == 0) {
+		return NULL;
+	}
+
+	if (resolver->_cur_axfr_pkt) {
+		if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
+			ldns_pkt_free(resolver->_cur_axfr_pkt);
+			resolver->_cur_axfr_pkt = NULL;
+			return ldns_axfr_next(resolver);
+		}
+		cur_rr = ldns_rr_clone(ldns_rr_list_rr(
+					ldns_pkt_answer(resolver->_cur_axfr_pkt),
+					resolver->_axfr_i));
+		resolver->_axfr_i++;
+		if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
+			resolver->_axfr_soa_count++;
+			if (resolver->_axfr_soa_count >= 2) {
+#ifndef USE_WINSOCK
+				close(resolver->_socket);
+#else
+				closesocket(resolver->_socket);
+#endif
+				resolver->_socket = 0;
+				ldns_pkt_free(resolver->_cur_axfr_pkt);
+				resolver->_cur_axfr_pkt = NULL;
+			}
+		}
+		return cur_rr;
+	} else {
+               packet_wire = ldns_tcp_read_wire_timeout(resolver->_socket, &packet_wire_size, resolver->_timeout);
+		if(!packet_wire)
+			return NULL;
+
+		status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
+				     packet_wire_size);
+		LDNS_FREE(packet_wire);
+
+		resolver->_axfr_i = 0;
+		if (status != LDNS_STATUS_OK) {
+			/* TODO: make status return type of this function (...api change) */
+#ifdef STDERR_MSGS
+			fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
+#endif
+
+			/* we must now also close the socket, otherwise subsequent uses of the
+			   same resolver structure will fail because the link is still open or
+			   in an undefined state */
+#ifndef USE_WINSOCK
+			close(resolver->_socket);
+#else
+			closesocket(resolver->_socket);
+#endif
+			resolver->_socket = 0;
+
+			return NULL;
+		} else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
+#ifdef STDERR_MSGS
+			ldns_lookup_table *rcode = ldns_lookup_by_id(
+				ldns_rcodes,(int) ldns_pkt_get_rcode(
+				resolver->_cur_axfr_pkt));
+			if (rcode) {
+				fprintf(stderr, "Error in AXFR: %s\n", 
+						rcode->name);
+			} else {
+				fprintf(stderr, "Error in AXFR: %d\n", 
+						(int) ldns_pkt_get_rcode(
+						resolver->_cur_axfr_pkt));
+			}
+#endif
+
+			/* we must now also close the socket, otherwise subsequent uses of the
+			   same resolver structure will fail because the link is still open or
+			   in an undefined state */
+#ifndef USE_WINSOCK
+			close(resolver->_socket);
+#else
+			closesocket(resolver->_socket);
+#endif
+			resolver->_socket = 0;
+
+			return NULL;
+		} else {
+			return ldns_axfr_next(resolver);
+		}
+
+	}
+
+}
+
+/* this function is needed to abort a transfer that is in progress;
+ * without it an aborted transfer will lead to the AXFR code in the
+ * library staying in an indetermined state because the socket for the
+ * AXFR is never closed
+ */
+void
+ldns_axfr_abort(ldns_resolver *resolver)
+{
+	/* Only abort if an actual AXFR is in progress */
+	if (resolver->_socket != 0)
+	{
+#ifndef USE_WINSOCK
+		close(resolver->_socket);
+#else
+		closesocket(resolver->_socket);
+#endif
+		resolver->_socket = 0;
+	}
+}
+
+bool
+ldns_axfr_complete(const ldns_resolver *res)
+{
+	/* complete when soa count is 2? */
+	return res->_axfr_soa_count == 2;
+}
+
+ldns_pkt *
+ldns_axfr_last_pkt(const ldns_resolver *res)
+{
+	return res->_cur_axfr_pkt;
+}
+
+void
+ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial)
+{
+	r->_serial = serial;
+}
+
+uint32_t
+ldns_resolver_get_ixfr_serial(const ldns_resolver *res)
+{
+	return res->_serial;
+}
+
+
+/* random isn't really that good */
+void
+ldns_resolver_nameservers_randomize(ldns_resolver *r)
+{
+	uint16_t i, j;
+	ldns_rdf **ns, *tmpns;
+	size_t *rtt, tmprtt;
+
+	/* should I check for ldns_resolver_random?? */
+	assert(r != NULL);
+
+	ns = ldns_resolver_nameservers(r);
+	rtt = ldns_resolver_rtt(r);
+	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
+		j = ldns_get_random() % ldns_resolver_nameserver_count(r);
+		tmpns = ns[i];
+		ns[i] = ns[j];
+		ns[j] = tmpns;
+		tmprtt = rtt[i];
+		rtt[i] = rtt[j];
+		rtt[j] = tmprtt;
+	}
+	ldns_resolver_set_nameservers(r, ns);
+}
+
diff --git a/ldns/src/rr.c b/ldns/src/rr.c
new file mode 100644
index 0000000..e52ea80
--- /dev/null
+++ b/ldns/src/rr.c
@@ -0,0 +1,2705 @@
+/* rr.c
+ *
+ * access functions for ldns_rr -
+ * a Net::DNS like library for C
+ * LibDNS Team @ NLnet Labs
+ *
+ * (c) NLnet Labs, 2004-2006
+ * See the file LICENSE for the license
+ */
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <strings.h>
+#include <limits.h>
+
+#include <errno.h>
+
+#define LDNS_SYNTAX_DATALEN 16
+#define LDNS_TTL_DATALEN    21
+#define LDNS_RRLIST_INIT    8
+
+ldns_rr *
+ldns_rr_new(void)
+{
+	ldns_rr *rr;
+	rr = LDNS_MALLOC(ldns_rr);
+        if (!rr) {
+                return NULL;
+	}
+
+	ldns_rr_set_owner(rr, NULL);
+	ldns_rr_set_question(rr, false);
+	ldns_rr_set_rd_count(rr, 0);
+	rr->_rdata_fields = NULL;
+	ldns_rr_set_class(rr, LDNS_RR_CLASS_IN);
+	ldns_rr_set_ttl(rr, LDNS_DEFAULT_TTL);
+        return rr;
+}
+
+ldns_rr *
+ldns_rr_new_frm_type(ldns_rr_type t)
+{
+	ldns_rr *rr;
+	const ldns_rr_descriptor *desc;
+	size_t i;
+
+	rr = LDNS_MALLOC(ldns_rr);
+        if (!rr) {
+                return NULL;
+	}
+
+	desc = ldns_rr_descript(t);
+
+	rr->_rdata_fields = LDNS_XMALLOC(ldns_rdf *, ldns_rr_descriptor_minimum(desc));
+        if(!rr->_rdata_fields) {
+                LDNS_FREE(rr);
+                return NULL;
+        }
+	for (i = 0; i < ldns_rr_descriptor_minimum(desc); i++) {
+		rr->_rdata_fields[i] = NULL;
+	}
+
+	ldns_rr_set_owner(rr, NULL);
+	ldns_rr_set_question(rr, false);
+	/* set the count to minimum */
+	ldns_rr_set_rd_count(rr, ldns_rr_descriptor_minimum(desc));
+	ldns_rr_set_class(rr, LDNS_RR_CLASS_IN);
+	ldns_rr_set_ttl(rr, LDNS_DEFAULT_TTL);
+	ldns_rr_set_type(rr, t);
+	return rr;
+}
+
+void
+ldns_rr_free(ldns_rr *rr)
+{
+	size_t i;
+	if (rr) {
+		if (ldns_rr_owner(rr)) {
+			ldns_rdf_deep_free(ldns_rr_owner(rr));
+		}
+		for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+			ldns_rdf_deep_free(ldns_rr_rdf(rr, i));
+		}
+		LDNS_FREE(rr->_rdata_fields);
+		LDNS_FREE(rr);
+	}
+}
+
+/* Syntactic sugar for ldns_rr_new_frm_str_internal */
+INLINE bool
+ldns_rdf_type_maybe_quoted(ldns_rdf_type rdf_type)
+{
+	return  rdf_type == LDNS_RDF_TYPE_STR ||
+		rdf_type == LDNS_RDF_TYPE_LONG_STR;
+}
+
+/*
+ * trailing spaces are allowed
+ * leading spaces are not allowed
+ * allow ttl to be optional
+ * class is optional too
+ * if ttl is missing, and default_ttl is 0, use DEF_TTL
+ * allow ttl to be written as 1d3h
+ * So the RR should look like. e.g.
+ * miek.nl. 3600 IN MX 10 elektron.atoom.net
+ * or
+ * miek.nl. 1h IN MX 10 elektron.atoom.net
+ * or
+ * miek.nl. IN MX 10 elektron.atoom.net
+ */
+static ldns_status
+ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
+                             uint32_t default_ttl, ldns_rdf *origin,
+		             ldns_rdf **prev, bool question)
+{
+	ldns_rr *new;
+	const ldns_rr_descriptor *desc;
+	ldns_rr_type rr_type;
+	ldns_buffer *rr_buf = NULL;
+	ldns_buffer *rd_buf = NULL;
+	uint32_t ttl_val;
+	char  *owner = NULL;
+	char  *ttl = NULL;
+	ldns_rr_class clas_val;
+	char  *clas = NULL;
+	char  *type = NULL;
+	char  *rdata = NULL;
+	char  *rd = NULL;
+	char  *xtok = NULL; /* For RDF types with spaces (i.e. extra tokens) */
+	size_t rd_strlen;
+	const char *delimiters;
+	ssize_t c;
+	ldns_rdf *owner_dname;
+        const char* endptr;
+        int was_unknown_rr_format = 0;
+	ldns_status status = LDNS_STATUS_OK;
+
+	/* used for types with unknown number of rdatas */
+	bool done;
+	bool quoted;
+
+	ldns_rdf *r = NULL;
+	uint16_t r_cnt;
+	uint16_t r_min;
+	uint16_t r_max;
+        size_t pre_data_pos;
+
+	uint16_t hex_data_size;
+	char *hex_data_str = NULL;
+	uint16_t cur_hex_data_size;
+	size_t hex_pos = 0;
+	uint8_t *hex_data = NULL;
+
+	new = ldns_rr_new();
+
+	owner = LDNS_XMALLOC(char, LDNS_MAX_DOMAINLEN + 1);
+	ttl = LDNS_XMALLOC(char, LDNS_TTL_DATALEN);
+	clas = LDNS_XMALLOC(char, LDNS_SYNTAX_DATALEN);
+	rdata = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN + 1);
+	rr_buf = LDNS_MALLOC(ldns_buffer);
+	rd_buf = LDNS_MALLOC(ldns_buffer);
+	rd = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
+	xtok = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
+	if (rr_buf) {
+		rr_buf->_data = NULL;
+	}
+	if (rd_buf) {
+		rd_buf->_data = NULL;
+	}
+	if (!new || !owner || !ttl || !clas || !rdata ||
+			!rr_buf || !rd_buf || !rd || !xtok) {
+
+		goto memerror;
+	}
+
+	ldns_buffer_new_frm_data(rr_buf, (char*)str, strlen(str));
+
+	/* split the rr in its parts -1 signals trouble */
+	if (ldns_bget_token(rr_buf, owner, "\t\n ", LDNS_MAX_DOMAINLEN) == -1){
+
+		status = LDNS_STATUS_SYNTAX_ERR;
+		goto error;
+	}
+
+	if (ldns_bget_token(rr_buf, ttl, "\t\n ", LDNS_TTL_DATALEN) == -1) {
+
+		status = LDNS_STATUS_SYNTAX_TTL_ERR;
+		goto error;
+	}
+	ttl_val = (uint32_t) ldns_str2period(ttl, &endptr);
+
+	if (strlen(ttl) > 0 && !isdigit((int) ttl[0])) {
+		/* ah, it's not there or something */
+		if (default_ttl == 0) {
+			ttl_val = LDNS_DEFAULT_TTL;
+		} else {
+			ttl_val = default_ttl;
+		}
+		/* we not ASSUMING the TTL is missing and that
+		 * the rest of the RR is still there. That is
+		 * CLASS TYPE RDATA
+		 * so ttl value we read is actually the class
+		 */
+		clas_val = ldns_get_rr_class_by_name(ttl);
+		/* class can be left out too, assume IN, current
+		 * token must be type
+		 */
+		if (clas_val == 0) {
+			clas_val = LDNS_RR_CLASS_IN;
+			type = LDNS_XMALLOC(char, strlen(ttl) + 1);
+			if (!type) {
+				goto memerror;
+			}
+			strncpy(type, ttl, strlen(ttl) + 1);
+		}
+	} else {
+		if (-1 == ldns_bget_token(
+				rr_buf, clas, "\t\n ", LDNS_SYNTAX_DATALEN)) {
+
+			status = LDNS_STATUS_SYNTAX_CLASS_ERR;
+			goto error;
+		}
+		clas_val = ldns_get_rr_class_by_name(clas);
+		/* class can be left out too, assume IN, current
+		 * token must be type
+		 */
+		if (clas_val == 0) {
+			clas_val = LDNS_RR_CLASS_IN;
+			type = LDNS_XMALLOC(char, strlen(clas) + 1);
+			if (!type) {
+				goto memerror;
+			}
+			strncpy(type, clas, strlen(clas) + 1);
+		}
+	}
+	/* the rest should still be waiting for us */
+
+	if (!type) {
+		type = LDNS_XMALLOC(char, LDNS_SYNTAX_DATALEN);
+		if (!type) {
+			goto memerror;
+		}
+		if (-1 == ldns_bget_token(
+				rr_buf, type, "\t\n ", LDNS_SYNTAX_DATALEN)) {
+
+			status = LDNS_STATUS_SYNTAX_TYPE_ERR;
+			goto error;
+		}
+	}
+
+	if (ldns_bget_token(rr_buf, rdata, "\0", LDNS_MAX_PACKETLEN) == -1) {
+		/* apparently we are done, and it's only a question RR
+		 * so do not set status and go to ldnserror here
+		 */
+	}
+	ldns_buffer_new_frm_data(rd_buf, rdata, strlen(rdata));
+
+	if (strlen(owner) <= 1 && strncmp(owner, "@", 1) == 0) {
+		if (origin) {
+			ldns_rr_set_owner(new, ldns_rdf_clone(origin));
+		} else if (prev && *prev) {
+			ldns_rr_set_owner(new, ldns_rdf_clone(*prev));
+		} else {
+			/* default to root */
+			ldns_rr_set_owner(new, ldns_dname_new_frm_str("."));
+		}
+
+		/* @ also overrides prev */
+		if (prev) {
+			ldns_rdf_deep_free(*prev);
+			*prev = ldns_rdf_clone(ldns_rr_owner(new));
+			if (!*prev) {
+				goto memerror;
+			}
+		}
+	} else {
+		if (strlen(owner) == 0) {
+			/* no ownername was given, try prev, if that fails
+			 * origin, else default to root */
+			if (prev && *prev) {
+				ldns_rr_set_owner(new, ldns_rdf_clone(*prev));
+			} else if (origin) {
+				ldns_rr_set_owner(new, ldns_rdf_clone(origin));
+			} else {
+				ldns_rr_set_owner(new,
+						ldns_dname_new_frm_str("."));
+			}
+			if(!ldns_rr_owner(new)) {
+				goto memerror;
+			}
+		} else {
+			owner_dname = ldns_dname_new_frm_str(owner);
+			if (!owner_dname) {
+				status = LDNS_STATUS_SYNTAX_ERR;
+				goto error;
+			}
+
+			ldns_rr_set_owner(new, owner_dname);
+			if (!ldns_dname_str_absolute(owner) && origin) {
+				if(ldns_dname_cat(ldns_rr_owner(new), origin)
+						!= LDNS_STATUS_OK) {
+
+					status = LDNS_STATUS_SYNTAX_ERR;
+					goto error;
+				}
+			}
+			if (prev) {
+				ldns_rdf_deep_free(*prev);
+				*prev = ldns_rdf_clone(ldns_rr_owner(new));
+				if (!*prev) {
+					goto error;
+				}
+			}
+		}
+	}
+	LDNS_FREE(owner);
+
+	ldns_rr_set_question(new, question);
+
+	ldns_rr_set_ttl(new, ttl_val);
+	LDNS_FREE(ttl);
+
+	ldns_rr_set_class(new, clas_val);
+	LDNS_FREE(clas);
+
+	rr_type = ldns_get_rr_type_by_name(type);
+	LDNS_FREE(type);
+
+	desc = ldns_rr_descript((uint16_t)rr_type);
+	ldns_rr_set_type(new, rr_type);
+	if (desc) {
+		/* only the rdata remains */
+		r_max = ldns_rr_descriptor_maximum(desc);
+		r_min = ldns_rr_descriptor_minimum(desc);
+	} else {
+		r_min = 0;
+		r_max = 1;
+	}
+
+	for (done = false, r_cnt = 0; !done && r_cnt < r_max; r_cnt++) {
+		quoted = false;
+
+		switch (ldns_rr_descriptor_field_type(desc, r_cnt)) {
+		case LDNS_RDF_TYPE_B64        :
+		case LDNS_RDF_TYPE_HEX        : /* These rdf types may con- */
+		case LDNS_RDF_TYPE_LOC        : /* tain whitespace, only if */
+		case LDNS_RDF_TYPE_WKS        : /* it is the last rd field. */
+		case LDNS_RDF_TYPE_IPSECKEY   :
+		case LDNS_RDF_TYPE_NSEC       :	if (r_cnt == r_max - 1) {
+							delimiters = "\n";
+							break;
+						}
+		default                       :	delimiters = "\n\t "; 
+		}
+
+		if (ldns_rdf_type_maybe_quoted(
+				ldns_rr_descriptor_field_type(
+				desc, r_cnt)) &&
+				ldns_buffer_remaining(rd_buf) > 0){
+
+			/* skip spaces */
+			while (*(ldns_buffer_current(rd_buf)) == ' ') {
+				ldns_buffer_skip(rd_buf, 1);
+			}
+
+			if (*(ldns_buffer_current(rd_buf)) == '\"') {
+				delimiters = "\"\0";
+				ldns_buffer_skip(rd_buf, 1);
+				quoted = true;
+			}
+		}
+
+		/* because number of fields can be variable, we can't rely on
+		 * _maximum() only
+		 */
+
+		/* skip spaces */
+		while (ldns_buffer_position(rd_buf) < ldns_buffer_limit(rd_buf)
+				&& *(ldns_buffer_current(rd_buf)) == ' '
+				&& !quoted) {
+
+			ldns_buffer_skip(rd_buf, 1);
+		}
+
+		pre_data_pos = ldns_buffer_position(rd_buf);
+		if (-1 == (c = ldns_bget_token(
+				rd_buf, rd, delimiters, LDNS_MAX_RDFLEN))) {
+
+			done = true;
+			break;
+		}
+		/* hmmz, rfc3597 specifies that any type can be represented 
+		 * with \# method, which can contain spaces...
+		 * it does specify size though...
+		 */
+		rd_strlen = strlen(rd);
+
+		/* unknown RR data */
+		if (strncmp(rd, "\\#", 2) == 0 && !quoted &&
+				(rd_strlen == 2 || rd[2]==' ')) {
+
+			was_unknown_rr_format = 1;
+			/* go back to before \#
+			 * and skip it while setting delimiters better
+			 */
+			ldns_buffer_set_position(rd_buf, pre_data_pos);
+			delimiters = "\n\t ";
+			(void)ldns_bget_token(rd_buf, rd,
+					delimiters, LDNS_MAX_RDFLEN);
+			/* read rdata octet length */
+			c = ldns_bget_token(rd_buf, rd,
+					delimiters, LDNS_MAX_RDFLEN);
+			if (c == -1) {
+				/* something goes very wrong here */
+				status = LDNS_STATUS_SYNTAX_RDATA_ERR;
+				goto error;
+			}
+			hex_data_size = (uint16_t) atoi(rd);
+			/* copy hex chars into hex str (2 chars per byte) */
+			hex_data_str = LDNS_XMALLOC(char, 2*hex_data_size + 1);
+			if (!hex_data_str) {
+				/* malloc error */
+				goto memerror;
+			}
+			cur_hex_data_size = 0;
+			while(cur_hex_data_size < 2 * hex_data_size) {
+				c = ldns_bget_token(rd_buf, rd,
+						delimiters, LDNS_MAX_RDFLEN);
+				if (c != -1) {
+					rd_strlen = strlen(rd);
+				}
+				if (c == -1 || 
+				    (size_t)cur_hex_data_size + rd_strlen >
+				    2 * (size_t)hex_data_size) {
+
+					status = LDNS_STATUS_SYNTAX_RDATA_ERR;
+					goto error;
+				}
+				strncpy(hex_data_str + cur_hex_data_size, rd,
+						rd_strlen);
+
+				cur_hex_data_size += rd_strlen;
+			}
+			hex_data_str[cur_hex_data_size] = '\0';
+
+			/* correct the rdf type */
+			/* if *we* know the type, interpret it as wireformat */
+			if (desc) {
+				hex_pos = 0;
+				hex_data =
+					LDNS_XMALLOC(uint8_t, hex_data_size+2);
+
+				if (!hex_data) {
+					goto memerror;
+				}
+				ldns_write_uint16(hex_data, hex_data_size);
+				ldns_hexstring_to_data(
+						hex_data + 2, hex_data_str);
+				status = ldns_wire2rdf(new, hex_data,
+						hex_data_size + 2, &hex_pos);
+				if (status != LDNS_STATUS_OK) {
+					goto error;
+				}
+				LDNS_FREE(hex_data);
+			} else {
+				r = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_HEX,
+						hex_data_str);
+				if (!r) {
+					goto memerror;
+				}
+				ldns_rdf_set_type(r, LDNS_RDF_TYPE_UNKNOWN);
+				if (!ldns_rr_push_rdf(new, r)) {
+					goto memerror;
+				}
+			}
+			LDNS_FREE(hex_data_str);
+
+		} else if(rd_strlen > 0 || quoted) {
+			/* Normal RR */
+			switch(ldns_rr_descriptor_field_type(desc, r_cnt)) {
+
+			case LDNS_RDF_TYPE_HEX:
+			case LDNS_RDF_TYPE_B64:
+				/* When this is the last rdata field, then the
+				 * rest should be read in (cause then these
+				 * rdf types may contain spaces).
+				 */
+				if (r_cnt == r_max - 1) {
+					c = ldns_bget_token(rd_buf, xtok,
+							"\n", LDNS_MAX_RDFLEN);
+					if (c != -1) {
+						(void) strncat(rd, xtok,
+							LDNS_MAX_RDFLEN -
+							strlen(rd) - 1);
+					}
+				}
+				r = ldns_rdf_new_frm_str(
+						ldns_rr_descriptor_field_type(
+							desc, r_cnt), rd);
+				break;
+
+			case LDNS_RDF_TYPE_HIP:
+				/*
+				 * In presentation format this RDATA type has
+				 * three tokens: An algorithm byte, then a
+				 * variable length HIT (in hexbytes) and then
+				 * a variable length Public Key (in base64).
+				 *
+				 * We have just read the algorithm, so we need
+				 * two more tokens: HIT and Public Key.
+				 */
+				do {
+					/* Read and append HIT */
+					if (ldns_bget_token(rd_buf,
+							xtok, delimiters,
+							LDNS_MAX_RDFLEN) == -1)
+						break;
+
+					(void) strncat(rd, " ",
+							LDNS_MAX_RDFLEN -
+							strlen(rd) - 1);
+					(void) strncat(rd, xtok,
+							LDNS_MAX_RDFLEN -
+							strlen(rd) - 1);
+
+					/* Read and append Public Key*/
+					if (ldns_bget_token(rd_buf,
+							xtok, delimiters,
+							LDNS_MAX_RDFLEN) == -1)
+						break;
+
+					(void) strncat(rd, " ",
+							LDNS_MAX_RDFLEN -
+							strlen(rd) - 1);
+					(void) strncat(rd, xtok,
+							LDNS_MAX_RDFLEN -
+							strlen(rd) - 1);
+				} while (false);
+
+				r = ldns_rdf_new_frm_str(
+						ldns_rr_descriptor_field_type(
+							desc, r_cnt), rd);
+				break;
+
+			case LDNS_RDF_TYPE_DNAME:
+				r = ldns_rdf_new_frm_str(
+						ldns_rr_descriptor_field_type(
+							desc, r_cnt), rd);
+
+				/* check if the origin should be used
+				 * or concatenated
+				 */
+				if (r && ldns_rdf_size(r) > 1 &&
+						ldns_rdf_data(r)[0] == 1 &&
+						ldns_rdf_data(r)[1] == '@') {
+
+					ldns_rdf_deep_free(r);
+
+					r = origin ? ldns_rdf_clone(origin)
+
+					  : ( rr_type == LDNS_RR_TYPE_SOA ?
+
+					      ldns_rdf_clone(
+						      ldns_rr_owner(new))
+
+					    : ldns_rdf_new_frm_str(
+						    LDNS_RDF_TYPE_DNAME, ".")
+					    );
+
+				} else if (r && rd_strlen >= 1 && origin &&
+						!ldns_dname_str_absolute(rd)) {
+
+					status = ldns_dname_cat(r, origin);
+					if (status != LDNS_STATUS_OK) {
+						goto error;
+					}
+				}
+				break;
+			default:
+				r = ldns_rdf_new_frm_str(
+						ldns_rr_descriptor_field_type(
+							desc, r_cnt), rd);
+				break;
+			}
+			if (!r) {
+				status = LDNS_STATUS_SYNTAX_RDATA_ERR;
+				goto error;
+			}
+			ldns_rr_push_rdf(new, r);
+		}
+		if (quoted) {
+			if (ldns_buffer_available(rd_buf, 1)) {
+				ldns_buffer_skip(rd_buf, 1);
+			} else {
+				done = true;
+			}
+		}
+
+	} /* for (done = false, r_cnt = 0; !done && r_cnt < r_max; r_cnt++) */
+	LDNS_FREE(rd);
+	LDNS_FREE(xtok);
+	ldns_buffer_free(rd_buf);
+	ldns_buffer_free(rr_buf);
+	LDNS_FREE(rdata);
+
+	if (!question && desc && !was_unknown_rr_format &&
+			ldns_rr_rd_count(new) < r_min) {
+
+		ldns_rr_free(new);
+		return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
+	}
+
+	if (newrr) {
+		*newrr = new;
+	} else {
+		/* Maybe the caller just wanted to see if it would parse? */
+		ldns_rr_free(new);
+	}
+	return LDNS_STATUS_OK;
+
+memerror:
+	status = LDNS_STATUS_MEM_ERR;
+error:
+	if (rd_buf && rd_buf->_data) {
+		ldns_buffer_free(rd_buf);
+	} else {
+		LDNS_FREE(rd_buf);
+	}
+	if (rr_buf && rr_buf->_data) {
+		ldns_buffer_free(rr_buf);
+	} else {
+		LDNS_FREE(rr_buf);
+	}
+	LDNS_FREE(type);
+	LDNS_FREE(owner);
+	LDNS_FREE(ttl);
+	LDNS_FREE(clas);
+	LDNS_FREE(hex_data);
+	LDNS_FREE(hex_data_str);
+	LDNS_FREE(xtok);
+	LDNS_FREE(rd);
+	LDNS_FREE(rdata);
+	ldns_rr_free(new);
+	return status;
+}
+
+ldns_status
+ldns_rr_new_frm_str(ldns_rr **newrr, const char *str,
+                    uint32_t default_ttl, ldns_rdf *origin,
+		    ldns_rdf **prev)
+{
+	return ldns_rr_new_frm_str_internal(newrr,
+	                                    str,
+	                                    default_ttl,
+	                                    origin,
+	                                    prev,
+	                                    false);
+}
+
+ldns_status
+ldns_rr_new_question_frm_str(ldns_rr **newrr, const char *str,
+                             ldns_rdf *origin, ldns_rdf **prev)
+{
+	return ldns_rr_new_frm_str_internal(newrr,
+	                                    str,
+	                                    0,
+	                                    origin,
+	                                    prev,
+	                                    true);
+}
+
+/* Strip whitespace from the start and the end of <line>.  */
+static char *
+ldns_strip_ws(char *line)
+{
+	char *s = line, *e;
+
+	for (s = line; *s && isspace(*s); s++)
+		;
+
+	for (e = strchr(s, 0); e > s+2 && isspace(e[-1]) && e[-2] != '\\'; e--)
+		;
+	*e = 0;
+
+	return s;
+}
+
+ldns_status
+ldns_rr_new_frm_fp(ldns_rr **newrr, FILE *fp, uint32_t *ttl, ldns_rdf **origin, ldns_rdf **prev)
+{
+	return ldns_rr_new_frm_fp_l(newrr, fp, ttl, origin, prev, NULL);
+}
+
+ldns_status
+ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr)
+{
+	char *line;
+	const char *endptr;  /* unused */
+	ldns_rr *rr;
+	uint32_t ttl;
+	ldns_rdf *tmp;
+	ldns_status s;
+	ssize_t size;
+
+	if (default_ttl) {
+		ttl = *default_ttl;
+	} else {
+		ttl = 0;
+	}
+
+	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
+	if (!line) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	/* read an entire line in from the file */
+	if ((size = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, LDNS_MAX_LINELEN, line_nr)) == -1) {
+		LDNS_FREE(line);
+		/* if last line was empty, we are now at feof, which is not
+		 * always a parse error (happens when for instance last line
+		 * was a comment)
+		 */
+		return LDNS_STATUS_SYNTAX_ERR;
+	}
+
+	/* we can have the situation, where we've read ok, but still got
+	 * no bytes to play with, in this case size is 0
+	 */
+	if (size == 0) {
+		LDNS_FREE(line);
+		return LDNS_STATUS_SYNTAX_EMPTY;
+	}
+
+	if (strncmp(line, "$ORIGIN", 7) == 0 && isspace(line[7])) {
+		if (*origin) {
+			ldns_rdf_deep_free(*origin);
+			*origin = NULL;
+		}
+		tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME,
+				ldns_strip_ws(line + 8));
+		if (!tmp) {
+			/* could not parse what next to $ORIGIN */
+			LDNS_FREE(line);
+			return LDNS_STATUS_SYNTAX_DNAME_ERR;
+		}
+		*origin = tmp;
+		s = LDNS_STATUS_SYNTAX_ORIGIN;
+	} else if (strncmp(line, "$TTL", 4) == 0 && isspace(line[4])) {
+		if (default_ttl) {
+			*default_ttl = ldns_str2period(
+					ldns_strip_ws(line + 5), &endptr);
+		}
+		s = LDNS_STATUS_SYNTAX_TTL;
+	} else if (strncmp(line, "$INCLUDE", 8) == 0) {
+		s = LDNS_STATUS_SYNTAX_INCLUDE;
+	} else if (!*ldns_strip_ws(line)) {
+		LDNS_FREE(line);
+		return LDNS_STATUS_SYNTAX_EMPTY;
+	} else {
+		if (origin && *origin) {
+			s = ldns_rr_new_frm_str(&rr, (const char*) line, ttl, *origin, prev);
+		} else {
+			s = ldns_rr_new_frm_str(&rr, (const char*) line, ttl, NULL, prev);
+		}
+	}
+	LDNS_FREE(line);
+	if (s == LDNS_STATUS_OK) {
+		if (newrr) {
+			*newrr = rr;
+		} else {
+			/* Just testing if it would parse? */
+			ldns_rr_free(rr);
+		}
+	}
+	return s;
+}
+
+void
+ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
+{
+	rr->_owner = owner;
+}
+
+void
+ldns_rr_set_question(ldns_rr *rr, bool question)
+{
+   rr->_rr_question = question;
+}
+
+void
+ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
+{
+	rr->_ttl = ttl;
+}
+
+void
+ldns_rr_set_rd_count(ldns_rr *rr, size_t count)
+{
+	rr->_rd_count = count;
+}
+
+void
+ldns_rr_set_type(ldns_rr *rr, ldns_rr_type rr_type)
+{
+	rr->_rr_type = rr_type;
+}
+
+void
+ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class)
+{
+	rr->_rr_class = rr_class;
+}
+
+ldns_rdf *
+ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position)
+{
+	size_t rd_count;
+	ldns_rdf *pop;
+
+	rd_count = ldns_rr_rd_count(rr);
+	if (position < rd_count) {
+		/* dicard the old one */
+		pop = rr->_rdata_fields[position];
+		rr->_rdata_fields[position] = (ldns_rdf*)f;
+		return pop;
+	} else {
+		return NULL;
+	}
+}
+
+bool
+ldns_rr_push_rdf(ldns_rr *rr, const ldns_rdf *f)
+{
+	size_t rd_count;
+	ldns_rdf **rdata_fields;
+
+	rd_count = ldns_rr_rd_count(rr);
+
+	/* grow the array */
+	rdata_fields = LDNS_XREALLOC(
+		rr->_rdata_fields, ldns_rdf *, rd_count + 1);
+	if (!rdata_fields) {
+		return false;
+	}
+
+	/* add the new member */
+	rr->_rdata_fields = rdata_fields;
+	rr->_rdata_fields[rd_count] = (ldns_rdf*)f;
+
+	ldns_rr_set_rd_count(rr, rd_count + 1);
+	return true;
+}
+
+ldns_rdf *
+ldns_rr_pop_rdf(ldns_rr *rr)
+{
+	size_t rd_count;
+	ldns_rdf *pop;
+	ldns_rdf** newrd;
+
+	rd_count = ldns_rr_rd_count(rr);
+
+	if (rd_count == 0) {
+		return NULL;
+	}
+
+	pop = rr->_rdata_fields[rd_count - 1];
+
+	/* try to shrink the array */
+	if(rd_count > 1) {
+		newrd = LDNS_XREALLOC(
+			rr->_rdata_fields, ldns_rdf *, rd_count - 1);
+		if(newrd)
+			rr->_rdata_fields = newrd;
+	} else {
+		LDNS_FREE(rr->_rdata_fields);
+	}
+
+	ldns_rr_set_rd_count(rr, rd_count - 1);
+	return pop;
+}
+
+ldns_rdf *
+ldns_rr_rdf(const ldns_rr *rr, size_t nr)
+{
+	if (rr && nr < ldns_rr_rd_count(rr)) {
+		return rr->_rdata_fields[nr];
+	} else {
+		return NULL;
+	}
+}
+
+ldns_rdf *
+ldns_rr_owner(const ldns_rr *rr)
+{
+	return rr->_owner;
+}
+
+bool
+ldns_rr_is_question(const ldns_rr *rr)
+{
+   return rr->_rr_question;
+}
+
+uint32_t
+ldns_rr_ttl(const ldns_rr *rr)
+{
+	return rr->_ttl;
+}
+
+size_t
+ldns_rr_rd_count(const ldns_rr *rr)
+{
+	return rr->_rd_count;
+}
+
+ldns_rr_type
+ldns_rr_get_type(const ldns_rr *rr)
+{
+        return rr->_rr_type;
+}
+
+ldns_rr_class
+ldns_rr_get_class(const ldns_rr *rr)
+{
+        return rr->_rr_class;
+}
+
+/* rr_lists */
+
+size_t
+ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
+{
+	if (rr_list) {
+		return rr_list->_rr_count;
+	} else {
+		return 0;
+	}
+}
+
+ldns_rr *
+ldns_rr_list_set_rr(ldns_rr_list *rr_list, const ldns_rr *r, size_t count)
+{
+	ldns_rr *old;
+
+	if (count > ldns_rr_list_rr_count(rr_list)) {
+		return NULL;
+	}
+
+	old = ldns_rr_list_rr(rr_list, count);
+
+	/* overwrite old's pointer */
+	rr_list->_rrs[count] = (ldns_rr*)r;
+	return old;
+}
+
+void
+ldns_rr_list_set_rr_count(ldns_rr_list *rr_list, size_t count)
+{
+	assert(count <= rr_list->_rr_capacity);
+	rr_list->_rr_count = count;
+}
+
+ldns_rr *
+ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
+{
+	if (nr < ldns_rr_list_rr_count(rr_list)) {
+		return rr_list->_rrs[nr];
+	} else {
+		return NULL;
+	}
+}
+
+ldns_rr_list *
+ldns_rr_list_new(void)
+{
+	ldns_rr_list *rr_list = LDNS_MALLOC(ldns_rr_list);
+        if(!rr_list) return NULL;
+	rr_list->_rr_count = 0;
+	rr_list->_rr_capacity = 0;
+	rr_list->_rrs = NULL;
+	return rr_list;
+}
+
+void
+ldns_rr_list_free(ldns_rr_list *rr_list)
+{
+	if (rr_list) {
+		LDNS_FREE(rr_list->_rrs);
+		LDNS_FREE(rr_list);
+	}
+}
+
+void
+ldns_rr_list_deep_free(ldns_rr_list *rr_list)
+{
+	size_t i;
+
+	if (rr_list) {
+		for (i=0; i < ldns_rr_list_rr_count(rr_list); i++) {
+			ldns_rr_free(ldns_rr_list_rr(rr_list, i));
+		}
+		LDNS_FREE(rr_list->_rrs);
+		LDNS_FREE(rr_list);
+	}
+}
+
+
+/* add right to left. So we modify *left! */
+bool
+ldns_rr_list_cat(ldns_rr_list *left, ldns_rr_list *right)
+{
+	size_t r_rr_count;
+	size_t i;
+
+	if (!left) {
+		return false;
+	}
+
+	if (right) {
+		r_rr_count = ldns_rr_list_rr_count(right);
+	} else {
+		r_rr_count = 0;
+	}
+
+	/* push right to left */
+	for(i = 0; i < r_rr_count; i++) {
+		ldns_rr_list_push_rr(left, ldns_rr_list_rr(right, i));
+	}
+	return true;
+}
+
+ldns_rr_list *
+ldns_rr_list_cat_clone(ldns_rr_list *left, ldns_rr_list *right)
+{
+	size_t l_rr_count;
+	size_t r_rr_count;
+	size_t i;
+	ldns_rr_list *cat;
+
+	if (left) {
+		l_rr_count = ldns_rr_list_rr_count(left);
+	} else {
+		return ldns_rr_list_clone(right);
+	}
+
+	if (right) {
+		r_rr_count = ldns_rr_list_rr_count(right);
+	} else {
+		r_rr_count = 0;
+	}
+
+	cat = ldns_rr_list_new();
+
+	if (!cat) {
+		return NULL;
+	}
+
+	/* left */
+	for(i = 0; i < l_rr_count; i++) {
+		ldns_rr_list_push_rr(cat,
+				ldns_rr_clone(ldns_rr_list_rr(left, i)));
+	}
+	/* right */
+	for(i = 0; i < r_rr_count; i++) {
+		ldns_rr_list_push_rr(cat,
+				ldns_rr_clone(ldns_rr_list_rr(right, i)));
+	}
+	return cat;
+}
+
+ldns_rr_list *
+ldns_rr_list_subtype_by_rdf(ldns_rr_list *l, ldns_rdf *r, size_t pos)
+{
+	size_t i;
+	ldns_rr_list *subtyped;
+	ldns_rdf *list_rdf;
+
+	subtyped = ldns_rr_list_new();
+
+	for(i = 0; i < ldns_rr_list_rr_count(l); i++) {
+		list_rdf = ldns_rr_rdf(
+			ldns_rr_list_rr(l, i),
+			pos);
+		if (!list_rdf) {
+			/* pos is too large or any other error */
+			ldns_rr_list_deep_free(subtyped);
+			return NULL;
+		}
+
+		if (ldns_rdf_compare(list_rdf, r) == 0) {
+			/* a match */
+			ldns_rr_list_push_rr(subtyped,
+					ldns_rr_clone(ldns_rr_list_rr(l, i)));
+		}
+	}
+
+	if (ldns_rr_list_rr_count(subtyped) > 0) {
+		return subtyped;
+	} else {
+		ldns_rr_list_free(subtyped);
+		return NULL;
+	}
+}
+
+bool
+ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
+{
+	size_t rr_count;
+	size_t cap;
+
+	rr_count = ldns_rr_list_rr_count(rr_list);
+	cap = rr_list->_rr_capacity;
+
+	/* grow the array */
+	if(rr_count+1 > cap) {
+		ldns_rr **rrs;
+
+		if(cap == 0)
+			cap = LDNS_RRLIST_INIT;  /* initial list size */
+		else	cap *= 2;
+		rrs = LDNS_XREALLOC(rr_list->_rrs, ldns_rr *, cap);
+		if (!rrs) {
+			return false;
+		}
+		rr_list->_rrs = rrs;
+		rr_list->_rr_capacity = cap;
+	}
+
+	/* add the new member */
+	rr_list->_rrs[rr_count] = (ldns_rr*)rr;
+
+	ldns_rr_list_set_rr_count(rr_list, rr_count + 1);
+	return true;
+}
+
+bool
+ldns_rr_list_push_rr_list(ldns_rr_list *rr_list, const ldns_rr_list *push_list)
+{
+	size_t i;
+
+	for(i = 0; i < ldns_rr_list_rr_count(push_list); i++) {
+		if (!ldns_rr_list_push_rr(rr_list,
+				ldns_rr_list_rr(push_list, i))) {
+			return false;
+		}
+	}
+	return true;
+}
+
+ldns_rr *
+ldns_rr_list_pop_rr(ldns_rr_list *rr_list)
+{
+	size_t rr_count;
+	size_t cap;
+	ldns_rr *pop;
+
+	rr_count = ldns_rr_list_rr_count(rr_list);
+
+	if (rr_count == 0) {
+		return NULL;
+	}
+
+	cap = rr_list->_rr_capacity;
+	pop = ldns_rr_list_rr(rr_list, rr_count - 1);
+
+	/* shrink the array */
+	if(cap > LDNS_RRLIST_INIT && rr_count-1 <= cap/2) {
+                ldns_rr** a;
+		cap /= 2;
+                a = LDNS_XREALLOC(rr_list->_rrs, ldns_rr *, cap);
+                if(a) {
+		        rr_list->_rrs = a;
+		        rr_list->_rr_capacity = cap;
+                }
+	}
+
+	ldns_rr_list_set_rr_count(rr_list, rr_count - 1);
+
+	return pop;
+}
+
+ldns_rr_list *
+ldns_rr_list_pop_rr_list(ldns_rr_list *rr_list, size_t howmany)
+{
+	/* pop a number of rr's and put them in a rr_list */
+	ldns_rr_list *popped;
+	ldns_rr *p;
+	size_t i = howmany;
+
+	popped = ldns_rr_list_new();
+
+	if (!popped) {
+		return NULL;
+	}
+
+
+	while(i > 0 &&
+			(p = ldns_rr_list_pop_rr(rr_list)) != NULL) {
+		ldns_rr_list_push_rr(popped, p);
+		i--;
+	}
+
+	if (i == howmany) { /* so i <= 0 */
+		ldns_rr_list_free(popped);
+		return NULL;
+	} else {
+		return popped;
+	}
+}
+
+
+bool
+ldns_rr_list_contains_rr(const ldns_rr_list *rr_list, ldns_rr *rr)
+{
+	size_t i;
+
+	if (!rr_list || !rr || ldns_rr_list_rr_count(rr_list) == 0) {
+		return false;
+	}
+
+	for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
+		if (rr == ldns_rr_list_rr(rr_list, i)) {
+			return true;
+		} else if (ldns_rr_compare(rr, ldns_rr_list_rr(rr_list, i)) == 0) {
+			return true;
+		}
+	}
+	return false;
+}
+
+bool
+ldns_is_rrset(ldns_rr_list *rr_list)
+{
+	ldns_rr_type t;
+	ldns_rr_class c;
+	ldns_rdf *o;
+	ldns_rr *tmp;
+	size_t i;
+
+	if (!rr_list || ldns_rr_list_rr_count(rr_list) == 0) {
+		return false;
+	}
+
+	tmp = ldns_rr_list_rr(rr_list, 0);
+
+	t = ldns_rr_get_type(tmp);
+	c = ldns_rr_get_class(tmp);
+	o = ldns_rr_owner(tmp);
+
+	/* compare these with the rest of the rr_list, start with 1 */
+	for (i = 1; i < ldns_rr_list_rr_count(rr_list); i++) {
+		tmp = ldns_rr_list_rr(rr_list, i);
+		if (t != ldns_rr_get_type(tmp)) {
+			return false;
+		}
+		if (c != ldns_rr_get_class(tmp)) {
+			return false;
+		}
+		if (ldns_rdf_compare(o, ldns_rr_owner(tmp)) != 0) {
+			return false;
+		}
+	}
+	return true;
+}
+
+bool
+ldns_rr_set_push_rr(ldns_rr_list *rr_list, ldns_rr *rr)
+{
+	size_t rr_count;
+	size_t i;
+	ldns_rr *last;
+
+	assert(rr != NULL);
+
+	rr_count = ldns_rr_list_rr_count(rr_list);
+
+	if (rr_count == 0) {
+		/* nothing there, so checking it is
+		 * not needed */
+		return ldns_rr_list_push_rr(rr_list, rr);
+	} else {
+		/* check with the final rr in the rr_list */
+		last = ldns_rr_list_rr(rr_list, rr_count - 1);
+
+		if (ldns_rr_get_class(last) != ldns_rr_get_class(rr)) {
+			return false;
+		}
+		if (ldns_rr_get_type(last) != ldns_rr_get_type(rr)) {
+			return false;
+		}
+		/* only check if not equal to RRSIG */
+		if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
+			if (ldns_rr_ttl(last) != ldns_rr_ttl(rr)) {
+				return false;
+			}
+		}
+		if (ldns_rdf_compare(ldns_rr_owner(last),
+					ldns_rr_owner(rr)) != 0) {
+			return false;
+		}
+		/* ok, still alive - check if the rr already
+		 * exists - if so, dont' add it */
+		for(i = 0; i < rr_count; i++) {
+			if(ldns_rr_compare(
+					ldns_rr_list_rr(rr_list, i), rr) == 0) {
+				return false;
+			}
+		}
+		/* it's safe, push it */
+		return ldns_rr_list_push_rr(rr_list, rr);
+	}
+}
+
+ldns_rr *
+ldns_rr_set_pop_rr(ldns_rr_list *rr_list)
+{
+	return ldns_rr_list_pop_rr(rr_list);
+}
+
+ldns_rr_list *
+ldns_rr_list_pop_rrset(ldns_rr_list *rr_list)
+{
+	ldns_rr_list *rrset;
+	ldns_rr *last_rr = NULL;
+	ldns_rr *next_rr;
+
+	if (!rr_list) {
+		return NULL;
+	}
+
+	rrset = ldns_rr_list_new();
+	if (!last_rr) {
+		last_rr = ldns_rr_list_pop_rr(rr_list);
+		if (!last_rr) {
+			ldns_rr_list_free(rrset);
+			return NULL;
+		} else {
+			ldns_rr_list_push_rr(rrset, last_rr);
+		}
+	}
+
+	if (ldns_rr_list_rr_count(rr_list) > 0) {
+		next_rr = ldns_rr_list_rr(rr_list, ldns_rr_list_rr_count(rr_list) - 1);
+	} else {
+		next_rr = NULL;
+	}
+
+	while (next_rr) {
+		if (
+			ldns_rdf_compare(ldns_rr_owner(next_rr),
+					 ldns_rr_owner(last_rr)) == 0
+			&&
+			ldns_rr_get_type(next_rr) == ldns_rr_get_type(last_rr)
+			&&
+			ldns_rr_get_class(next_rr) == ldns_rr_get_class(last_rr)
+		   ) {
+			ldns_rr_list_push_rr(rrset, ldns_rr_list_pop_rr(rr_list));
+			if (ldns_rr_list_rr_count(rr_list) > 0) {
+				last_rr = next_rr;
+				next_rr = ldns_rr_list_rr(rr_list, ldns_rr_list_rr_count(rr_list) - 1);
+			} else {
+				next_rr = NULL;
+			}
+		} else {
+			next_rr = NULL;
+		}
+	}
+
+	return rrset;
+}
+
+ldns_rr *
+ldns_rr_clone(const ldns_rr *rr)
+{
+	size_t i;
+	ldns_rr *new_rr;
+
+	if (!rr) {
+		return NULL;
+	}
+
+	new_rr = ldns_rr_new();
+	if (!new_rr) {
+		return NULL;
+	}
+	if (ldns_rr_owner(rr)) {
+		ldns_rr_set_owner(new_rr, ldns_rdf_clone(ldns_rr_owner(rr)));
+  	}
+	ldns_rr_set_ttl(new_rr, ldns_rr_ttl(rr));
+	ldns_rr_set_type(new_rr, ldns_rr_get_type(rr));
+	ldns_rr_set_class(new_rr, ldns_rr_get_class(rr));
+	ldns_rr_set_question(new_rr, ldns_rr_is_question(rr));
+
+	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+        	if (ldns_rr_rdf(rr,i)) {
+        		ldns_rr_push_rdf(new_rr, ldns_rdf_clone(ldns_rr_rdf(rr, i)));
+                }
+	}
+
+	return new_rr;
+}
+
+ldns_rr_list *
+ldns_rr_list_clone(const ldns_rr_list *rrlist)
+{
+	size_t i;
+	ldns_rr_list *new_list;
+	ldns_rr *r;
+
+	if (!rrlist) {
+		return NULL;
+	}
+
+	new_list = ldns_rr_list_new();
+	if (!new_list) {
+		return NULL;
+	}
+	for (i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
+		r = ldns_rr_clone(
+			ldns_rr_list_rr(rrlist, i)
+		    );
+		if (!r) {
+			/* huh, failure in cloning */
+			ldns_rr_list_deep_free(new_list);
+			return NULL;
+		}
+		ldns_rr_list_push_rr(new_list, r);
+	}
+	return new_list;
+}
+
+
+static int
+qsort_schwartz_rr_compare(const void *a, const void *b)
+{
+	int result = 0;
+	ldns_rr *rr1, *rr2;
+	ldns_buffer *rr1_buf, *rr2_buf;
+	struct ldns_schwartzian_compare_struct *sa = *(struct ldns_schwartzian_compare_struct **) a;
+	struct ldns_schwartzian_compare_struct *sb = *(struct ldns_schwartzian_compare_struct **) b;
+	/* if we are doing 2wire, we need to do lowercasing on the dname (and maybe on the rdata)
+	 * this must be done for comparison only, so we need to have a temp var for both buffers,
+	 * which is only used when the transformed object value isn't there yet
+	 */
+	ldns_rr *canonical_a, *canonical_b;
+
+	rr1 = (ldns_rr *) sa->original_object;
+	rr2 = (ldns_rr *) sb->original_object;
+
+	result = ldns_rr_compare_no_rdata(rr1, rr2);
+
+	if (result == 0) {
+		if (!sa->transformed_object) {
+			canonical_a = ldns_rr_clone(sa->original_object);
+			ldns_rr2canonical(canonical_a);
+			sa->transformed_object = ldns_buffer_new(ldns_rr_uncompressed_size(canonical_a));
+			if (ldns_rr2buffer_wire(sa->transformed_object, canonical_a, LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
+		                ldns_buffer_free((ldns_buffer *)sa->transformed_object);
+                                sa->transformed_object = NULL;
+				ldns_rr_free(canonical_a);
+				return 0;
+			}
+			ldns_rr_free(canonical_a);
+		}
+		if (!sb->transformed_object) {
+			canonical_b = ldns_rr_clone(sb->original_object);
+			ldns_rr2canonical(canonical_b);
+			sb->transformed_object = ldns_buffer_new(ldns_rr_uncompressed_size(canonical_b));
+			if (ldns_rr2buffer_wire(sb->transformed_object, canonical_b, LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
+		                ldns_buffer_free((ldns_buffer *)sa->transformed_object);
+		                ldns_buffer_free((ldns_buffer *)sb->transformed_object);
+                                sa->transformed_object = NULL;
+                                sb->transformed_object = NULL;
+				ldns_rr_free(canonical_b);
+				return 0;
+			}
+			ldns_rr_free(canonical_b);
+		}
+		rr1_buf = (ldns_buffer *) sa->transformed_object;
+		rr2_buf = (ldns_buffer *) sb->transformed_object;
+
+		result = ldns_rr_compare_wire(rr1_buf, rr2_buf);
+	}
+
+	return result;
+}
+
+void
+ldns_rr_list_sort(ldns_rr_list *unsorted)
+{
+	struct ldns_schwartzian_compare_struct **sortables;
+	size_t item_count;
+	size_t i;
+
+	if (unsorted) {
+		item_count = ldns_rr_list_rr_count(unsorted);
+
+		sortables = LDNS_XMALLOC(struct ldns_schwartzian_compare_struct *,
+					 item_count);
+                if(!sortables) return; /* no way to return error */
+		for (i = 0; i < item_count; i++) {
+			sortables[i] = LDNS_XMALLOC(struct ldns_schwartzian_compare_struct, 1);
+                        if(!sortables[i]) {
+                                /* free the allocated parts */
+                                while(i>0) {
+                                        i--;
+                                        LDNS_FREE(sortables[i]);
+                                }
+                                /* no way to return error */
+				LDNS_FREE(sortables);
+                                return;
+                        }
+			sortables[i]->original_object = ldns_rr_list_rr(unsorted, i);
+			sortables[i]->transformed_object = NULL;
+		}
+		qsort(sortables,
+		      item_count,
+		      sizeof(struct ldns_schwartzian_compare_struct *),
+		      qsort_schwartz_rr_compare);
+		for (i = 0; i < item_count; i++) {
+			unsorted->_rrs[i] = sortables[i]->original_object;
+			if (sortables[i]->transformed_object) {
+				ldns_buffer_free(sortables[i]->transformed_object);
+			}
+			LDNS_FREE(sortables[i]);
+		}
+		LDNS_FREE(sortables);
+	}
+}
+
+int
+ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2)
+{
+	size_t rr1_len;
+	size_t rr2_len;
+        size_t offset;
+
+	assert(rr1 != NULL);
+	assert(rr2 != NULL);
+
+	rr1_len = ldns_rr_uncompressed_size(rr1);
+	rr2_len = ldns_rr_uncompressed_size(rr2);
+
+	if (ldns_dname_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)) < 0) {
+		return -1;
+	} else if (ldns_dname_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)) > 0) {
+		return 1;
+	}
+
+        /* should return -1 if rr1 comes before rr2, so need to do rr1 - rr2, not rr2 - rr1 */
+        if (ldns_rr_get_class(rr1) != ldns_rr_get_class(rr2)) {
+            return ldns_rr_get_class(rr1) - ldns_rr_get_class(rr2);
+        }
+
+        /* should return -1 if rr1 comes before rr2, so need to do rr1 - rr2, not rr2 - rr1 */
+        if (ldns_rr_get_type(rr1) != ldns_rr_get_type(rr2)) {
+            return ldns_rr_get_type(rr1) - ldns_rr_get_type(rr2);
+        }
+
+        /* offset is the owername length + ttl + type + class + rdlen == start of wire format rdata */
+        offset = ldns_rdf_size(ldns_rr_owner(rr1)) + 4 + 2 + 2 + 2;
+        /* if either record doesn't have any RDATA... */
+        if (offset > rr1_len || offset > rr2_len) {
+            if (rr1_len == rr2_len) {
+              return 0;
+            }
+            return ((int) rr2_len - (int) rr1_len);
+        }
+
+	return 0;
+}
+
+int ldns_rr_compare_wire(ldns_buffer *rr1_buf, ldns_buffer *rr2_buf)
+{
+        size_t rr1_len, rr2_len, min_len, i, offset;
+
+        rr1_len = ldns_buffer_capacity(rr1_buf);
+        rr2_len = ldns_buffer_capacity(rr2_buf);
+
+        /* jump past dname (checked in earlier part)
+         * and especially past TTL */
+        offset = 0;
+        while (offset < rr1_len && *ldns_buffer_at(rr1_buf, offset) != 0) {
+          offset += *ldns_buffer_at(rr1_buf, offset) + 1;
+        }
+        /* jump to rdata section (PAST the rdata length field, otherwise
+           rrs with different lengths might be sorted erroneously */
+        offset += 11;
+	   min_len = (rr1_len < rr2_len) ? rr1_len : rr2_len;
+        /* Compare RRs RDATA byte for byte. */
+        for(i = offset; i < min_len; i++) {
+                if (*ldns_buffer_at(rr1_buf,i) < *ldns_buffer_at(rr2_buf,i)) {
+                        return -1;
+                } else if (*ldns_buffer_at(rr1_buf,i) > *ldns_buffer_at(rr2_buf,i)) {
+                        return +1;
+                }
+        }
+
+        /* If both RDATAs are the same up to min_len, then the shorter one sorts first. */
+        if (rr1_len < rr2_len) {
+                return -1;
+        } else if (rr1_len > rr2_len) {
+                return +1;
+	}
+        /* The RDATAs are equal. */
+        return 0;
+
+}
+
+int
+ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
+{
+	int result;
+	size_t rr1_len, rr2_len;
+
+	ldns_buffer *rr1_buf;
+	ldns_buffer *rr2_buf;
+
+	result = ldns_rr_compare_no_rdata(rr1, rr2);
+	if (result == 0) {
+		rr1_len = ldns_rr_uncompressed_size(rr1);
+		rr2_len = ldns_rr_uncompressed_size(rr2);
+
+		rr1_buf = ldns_buffer_new(rr1_len);
+		rr2_buf = ldns_buffer_new(rr2_len);
+
+		if (ldns_rr2buffer_wire_canonical(rr1_buf,
+								    rr1,
+								    LDNS_SECTION_ANY)
+		    != LDNS_STATUS_OK) {
+			ldns_buffer_free(rr1_buf);
+			ldns_buffer_free(rr2_buf);
+			return 0;
+		}
+		if (ldns_rr2buffer_wire_canonical(rr2_buf,
+								    rr2,
+								    LDNS_SECTION_ANY)
+		    != LDNS_STATUS_OK) {
+			ldns_buffer_free(rr1_buf);
+			ldns_buffer_free(rr2_buf);
+			return 0;
+		}
+
+		result = ldns_rr_compare_wire(rr1_buf, rr2_buf);
+
+		ldns_buffer_free(rr1_buf);
+		ldns_buffer_free(rr2_buf);
+	}
+
+	return result;
+}
+
+/* convert dnskey to a ds with the given algorithm,
+ * then compare the result with the given ds */
+static int
+ldns_rr_compare_ds_dnskey(ldns_rr *ds,
+                          ldns_rr *dnskey)
+{
+	ldns_rr *ds_gen;
+	bool result = false;
+	ldns_hash algo;
+
+	if (!dnskey || !ds ||
+	    ldns_rr_get_type(ds) != LDNS_RR_TYPE_DS ||
+	    ldns_rr_get_type(dnskey) != LDNS_RR_TYPE_DNSKEY) {
+		return false;
+	}
+
+	if (ldns_rr_rdf(ds, 2) == NULL) {
+		return false;
+	}
+	algo = ldns_rdf2native_int8(ldns_rr_rdf(ds, 2));
+
+	ds_gen = ldns_key_rr2ds(dnskey, algo);
+	if (ds_gen) {
+		result = ldns_rr_compare(ds, ds_gen) == 0;
+		ldns_rr_free(ds_gen);
+	}
+	return result;
+}
+
+bool
+ldns_rr_compare_ds(const ldns_rr *orr1, const ldns_rr *orr2)
+{
+	bool result;
+	ldns_rr *rr1 = ldns_rr_clone(orr1);
+	ldns_rr *rr2 = ldns_rr_clone(orr2);
+
+	/* set ttls to zero */
+	ldns_rr_set_ttl(rr1, 0);
+	ldns_rr_set_ttl(rr2, 0);
+
+	if (ldns_rr_get_type(rr1) == LDNS_RR_TYPE_DS &&
+	    ldns_rr_get_type(rr2) == LDNS_RR_TYPE_DNSKEY) {
+		result = ldns_rr_compare_ds_dnskey(rr1, rr2);
+	} else if (ldns_rr_get_type(rr1) == LDNS_RR_TYPE_DNSKEY &&
+	    ldns_rr_get_type(rr2) == LDNS_RR_TYPE_DS) {
+		result = ldns_rr_compare_ds_dnskey(rr2, rr1);
+	} else {
+		result = (ldns_rr_compare(rr1, rr2) == 0);
+	}
+
+	ldns_rr_free(rr1);
+	ldns_rr_free(rr2);
+
+	return result;
+}
+
+int
+ldns_rr_list_compare(const ldns_rr_list *rrl1, const ldns_rr_list *rrl2)
+{
+	size_t i = 0;
+	int rr_cmp;
+
+	assert(rrl1 != NULL);
+	assert(rrl2 != NULL);
+
+	for (i = 0; i < ldns_rr_list_rr_count(rrl1) && i < ldns_rr_list_rr_count(rrl2); i++) {
+		rr_cmp = ldns_rr_compare(ldns_rr_list_rr(rrl1, i), ldns_rr_list_rr(rrl2, i));
+		if (rr_cmp != 0) {
+			return rr_cmp;
+		}
+	}
+
+	if (i == ldns_rr_list_rr_count(rrl1) &&
+	    i != ldns_rr_list_rr_count(rrl2)) {
+		return 1;
+	} else if (i == ldns_rr_list_rr_count(rrl2) &&
+	           i != ldns_rr_list_rr_count(rrl1)) {
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+size_t
+ldns_rr_uncompressed_size(const ldns_rr *r)
+{
+	size_t rrsize;
+	size_t i;
+
+	rrsize = 0;
+	/* add all the rdf sizes */
+	for(i = 0; i < ldns_rr_rd_count(r); i++) {
+		rrsize += ldns_rdf_size(ldns_rr_rdf(r, i));
+	}
+	/* ownername */
+	rrsize += ldns_rdf_size(ldns_rr_owner(r));
+	rrsize += LDNS_RR_OVERHEAD;
+	return rrsize;
+}
+
+void
+ldns_rr2canonical(ldns_rr *rr)
+{
+	uint16_t i;
+
+	if (!rr) {
+	  return;
+        }
+
+        ldns_dname2canonical(ldns_rr_owner(rr));
+
+	/*
+	 * lowercase the rdata dnames if the rr type is one
+	 * of the list in chapter 7 of RFC3597
+	 * Also added RRSIG, because a "Signer's Name" should be canonicalized
+	 * too. See dnssec-bis-updates-16. We can add it to this list because
+	 * the "Signer's Name"  is the only dname type rdata field in a RRSIG.
+	 */
+	switch(ldns_rr_get_type(rr)) {
+        	case LDNS_RR_TYPE_NS:
+        	case LDNS_RR_TYPE_MD:
+        	case LDNS_RR_TYPE_MF:
+        	case LDNS_RR_TYPE_CNAME:
+        	case LDNS_RR_TYPE_SOA:
+        	case LDNS_RR_TYPE_MB:
+        	case LDNS_RR_TYPE_MG:
+        	case LDNS_RR_TYPE_MR:
+        	case LDNS_RR_TYPE_PTR:
+        	case LDNS_RR_TYPE_MINFO:
+        	case LDNS_RR_TYPE_MX:
+        	case LDNS_RR_TYPE_RP:
+        	case LDNS_RR_TYPE_AFSDB:
+        	case LDNS_RR_TYPE_RT:
+        	case LDNS_RR_TYPE_SIG:
+        	case LDNS_RR_TYPE_PX:
+        	case LDNS_RR_TYPE_NXT:
+        	case LDNS_RR_TYPE_NAPTR:
+        	case LDNS_RR_TYPE_KX:
+        	case LDNS_RR_TYPE_SRV:
+        	case LDNS_RR_TYPE_DNAME:
+        	case LDNS_RR_TYPE_A6:
+        	case LDNS_RR_TYPE_RRSIG:
+			for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+				ldns_dname2canonical(ldns_rr_rdf(rr, i));
+			}
+			return;
+		default:
+			/* do nothing */
+			return;
+	}
+}
+
+void
+ldns_rr_list2canonical(ldns_rr_list *rr_list)
+{
+	size_t i;
+	for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
+		ldns_rr2canonical(ldns_rr_list_rr(rr_list, i));
+	}
+}
+
+uint8_t
+ldns_rr_label_count(ldns_rr *rr)
+{
+	if (!rr) {
+		return 0;
+	}
+	return ldns_dname_label_count(
+			ldns_rr_owner(rr));
+}
+
+/** \cond */
+static const ldns_rdf_type type_0_wireformat[] = { LDNS_RDF_TYPE_UNKNOWN };
+static const ldns_rdf_type type_a_wireformat[] = { LDNS_RDF_TYPE_A };
+static const ldns_rdf_type type_ns_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_md_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_mf_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_cname_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_soa_wireformat[] = {
+	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_INT32, 
+	LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_PERIOD,
+	LDNS_RDF_TYPE_PERIOD
+};
+static const ldns_rdf_type type_mb_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_mg_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_mr_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_wks_wireformat[] = {
+	LDNS_RDF_TYPE_A, LDNS_RDF_TYPE_WKS
+};
+static const ldns_rdf_type type_ptr_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_hinfo_wireformat[] = {
+	LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
+};
+static const ldns_rdf_type type_minfo_wireformat[] = {
+	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_mx_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_rp_wireformat[] = {
+	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_afsdb_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_x25_wireformat[] = { LDNS_RDF_TYPE_STR };
+static const ldns_rdf_type type_isdn_wireformat[] = {
+	LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
+};
+static const ldns_rdf_type type_rt_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_nsap_wireformat[] = {
+	LDNS_RDF_TYPE_NSAP
+};
+static const ldns_rdf_type type_nsap_ptr_wireformat[] = {
+	LDNS_RDF_TYPE_STR
+};
+static const ldns_rdf_type type_sig_wireformat[] = {
+	LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32,
+	LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_B64
+};
+static const ldns_rdf_type type_key_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_B64
+};
+static const ldns_rdf_type type_px_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_gpos_wireformat[] = {
+	LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
+};
+static const ldns_rdf_type type_aaaa_wireformat[] = { LDNS_RDF_TYPE_AAAA };
+static const ldns_rdf_type type_loc_wireformat[] = { LDNS_RDF_TYPE_LOC };
+static const ldns_rdf_type type_nxt_wireformat[] = {
+	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_UNKNOWN
+};
+static const ldns_rdf_type type_eid_wireformat[] = {
+	LDNS_RDF_TYPE_HEX
+};
+static const ldns_rdf_type type_nimloc_wireformat[] = {
+	LDNS_RDF_TYPE_HEX
+};
+static const ldns_rdf_type type_srv_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_atma_wireformat[] = {
+	LDNS_RDF_TYPE_ATMA
+};
+static const ldns_rdf_type type_naptr_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_kx_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_cert_wireformat[] = {
+	 LDNS_RDF_TYPE_CERT_ALG, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_B64
+};
+static const ldns_rdf_type type_a6_wireformat[] = { LDNS_RDF_TYPE_UNKNOWN };
+static const ldns_rdf_type type_dname_wireformat[] = { LDNS_RDF_TYPE_DNAME };
+static const ldns_rdf_type type_sink_wireformat[] = { LDNS_RDF_TYPE_INT8,
+	LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_B64
+};
+static const ldns_rdf_type type_apl_wireformat[] = {
+	LDNS_RDF_TYPE_APL
+};
+static const ldns_rdf_type type_ds_wireformat[] = {
+	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
+};
+static const ldns_rdf_type type_sshfp_wireformat[] = {
+	LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
+};
+static const ldns_rdf_type type_ipseckey_wireformat[] = {
+	LDNS_RDF_TYPE_IPSECKEY
+};
+static const ldns_rdf_type type_rrsig_wireformat[] = {
+	LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32,
+	LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_B64
+};
+static const ldns_rdf_type type_nsec_wireformat[] = {
+	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_NSEC
+};
+static const ldns_rdf_type type_dhcid_wireformat[] = {
+	LDNS_RDF_TYPE_B64
+};
+static const ldns_rdf_type type_talink_wireformat[] = {
+	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
+};
+/*@unused@*/ static const ldns_rdf_type type_openpgpkey_wireformat[] = {
+	LDNS_RDF_TYPE_B64
+};
+/* nsec3 is some vars, followed by same type of data of nsec */
+static const ldns_rdf_type type_nsec3_wireformat[] = {
+/*	LDNS_RDF_TYPE_NSEC3_VARS, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC*/
+	LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_NSEC3_SALT, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC
+};
+
+static const ldns_rdf_type type_nsec3param_wireformat[] = {
+/*	LDNS_RDF_TYPE_NSEC3_PARAMS_VARS*/
+	LDNS_RDF_TYPE_INT8,
+	LDNS_RDF_TYPE_INT8,
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_NSEC3_SALT
+};
+
+static const ldns_rdf_type type_dnskey_wireformat[] = {
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_INT8,
+	LDNS_RDF_TYPE_ALG,
+	LDNS_RDF_TYPE_B64
+};
+static const ldns_rdf_type type_tkey_wireformat[] = {
+	LDNS_RDF_TYPE_DNAME,
+	LDNS_RDF_TYPE_TIME,
+	LDNS_RDF_TYPE_TIME,
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_INT16_DATA,
+	LDNS_RDF_TYPE_INT16_DATA,
+};
+static const ldns_rdf_type type_tsig_wireformat[] = {
+	LDNS_RDF_TYPE_DNAME,
+	LDNS_RDF_TYPE_TSIGTIME,
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_INT16_DATA,
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_INT16_DATA
+};
+static const ldns_rdf_type type_tlsa_wireformat[] = {
+	LDNS_RDF_TYPE_CERTIFICATE_USAGE,
+	LDNS_RDF_TYPE_SELECTOR,
+	LDNS_RDF_TYPE_MATCHING_TYPE,
+	LDNS_RDF_TYPE_HEX
+};
+static const ldns_rdf_type type_hip_wireformat[] = {
+	LDNS_RDF_TYPE_HIP
+};
+static const ldns_rdf_type type_nid_wireformat[] = {
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_ILNP64
+};
+static const ldns_rdf_type type_l32_wireformat[] = {
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_A
+};
+static const ldns_rdf_type type_l64_wireformat[] = {
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_ILNP64
+};
+static const ldns_rdf_type type_lp_wireformat[] = {
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_DNAME
+};
+static const ldns_rdf_type type_eui48_wireformat[] = {
+	LDNS_RDF_TYPE_EUI48
+};
+static const ldns_rdf_type type_eui64_wireformat[] = {
+	LDNS_RDF_TYPE_EUI64
+};
+#ifdef RRTYPE_URI
+static const ldns_rdf_type type_uri_wireformat[] = {
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_INT16,
+	LDNS_RDF_TYPE_LONG_STR
+};
+#endif
+static const ldns_rdf_type type_caa_wireformat[] = {
+	LDNS_RDF_TYPE_INT8,
+	LDNS_RDF_TYPE_TAG,
+	LDNS_RDF_TYPE_LONG_STR
+};
+/** \endcond */
+
+/** \cond */
+/* All RR's defined in 1035 are well known and can thus
+ * be compressed. See RFC3597. These RR's are:
+ * CNAME HINFO MB MD MF MG MINFO MR MX NULL NS PTR SOA TXT
+ */
+static ldns_rr_descriptor rdata_field_descriptors[] = {
+	/* 0 */
+	{ 0, NULL, 0, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 1 */
+	{LDNS_RR_TYPE_A, "A", 1, 1, type_a_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 2 */
+	{LDNS_RR_TYPE_NS, "NS", 1, 1, type_ns_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 3 */
+	{LDNS_RR_TYPE_MD, "MD", 1, 1, type_md_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 4 */
+	{LDNS_RR_TYPE_MF, "MF", 1, 1, type_mf_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 5 */
+	{LDNS_RR_TYPE_CNAME, "CNAME", 1, 1, type_cname_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 6 */
+	{LDNS_RR_TYPE_SOA, "SOA", 7, 7, type_soa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 2 },
+	/* 7 */
+	{LDNS_RR_TYPE_MB, "MB", 1, 1, type_mb_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 8 */
+	{LDNS_RR_TYPE_MG, "MG", 1, 1, type_mg_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 9 */
+	{LDNS_RR_TYPE_MR, "MR", 1, 1, type_mr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 10 */
+	{LDNS_RR_TYPE_NULL, "NULL", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 11 */
+	{LDNS_RR_TYPE_WKS, "WKS", 2, 2, type_wks_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 12 */
+	{LDNS_RR_TYPE_PTR, "PTR", 1, 1, type_ptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 13 */
+	{LDNS_RR_TYPE_HINFO, "HINFO", 2, 2, type_hinfo_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 14 */
+	{LDNS_RR_TYPE_MINFO, "MINFO", 2, 2, type_minfo_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 2 },
+	/* 15 */
+	{LDNS_RR_TYPE_MX, "MX", 2, 2, type_mx_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
+	/* 16 */
+	{LDNS_RR_TYPE_TXT, "TXT", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
+	/* 17 */
+	{LDNS_RR_TYPE_RP, "RP", 2, 2, type_rp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
+	/* 18 */
+	{LDNS_RR_TYPE_AFSDB, "AFSDB", 2, 2, type_afsdb_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 19 */
+	{LDNS_RR_TYPE_X25, "X25", 1, 1, type_x25_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 20 */
+	{LDNS_RR_TYPE_ISDN, "ISDN", 1, 2, type_isdn_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 21 */
+	{LDNS_RR_TYPE_RT, "RT", 2, 2, type_rt_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 22 */
+	{LDNS_RR_TYPE_NSAP, "NSAP", 1, 1, type_nsap_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 23 */
+	{LDNS_RR_TYPE_NSAP_PTR, "NSAP-PTR", 1, 1, type_nsap_ptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 24 */
+	{LDNS_RR_TYPE_SIG, "SIG", 9, 9, type_sig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 25 */
+	{LDNS_RR_TYPE_KEY, "KEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 26 */
+	{LDNS_RR_TYPE_PX, "PX", 3, 3, type_px_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
+	/* 27 */
+	{LDNS_RR_TYPE_GPOS, "GPOS", 3, 3, type_gpos_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 28 */
+	{LDNS_RR_TYPE_AAAA, "AAAA", 1, 1, type_aaaa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 29 */
+	{LDNS_RR_TYPE_LOC, "LOC", 1, 1, type_loc_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 30 */
+	{LDNS_RR_TYPE_NXT, "NXT", 2, 2, type_nxt_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 31 */
+	{LDNS_RR_TYPE_EID, "EID", 1, 1, type_eid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 32 */
+	{LDNS_RR_TYPE_NIMLOC, "NIMLOC", 1, 1, type_nimloc_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 33 */
+	{LDNS_RR_TYPE_SRV, "SRV", 4, 4, type_srv_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 34 */
+	{LDNS_RR_TYPE_ATMA, "ATMA", 1, 1, type_atma_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 35 */
+	{LDNS_RR_TYPE_NAPTR, "NAPTR", 6, 6, type_naptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 36 */
+	{LDNS_RR_TYPE_KX, "KX", 2, 2, type_kx_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 37 */
+	{LDNS_RR_TYPE_CERT, "CERT", 4, 4, type_cert_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 38 */
+	{LDNS_RR_TYPE_A6, "A6", 1, 1, type_a6_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 39 */
+	{LDNS_RR_TYPE_DNAME, "DNAME", 1, 1, type_dname_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 40 */
+	{LDNS_RR_TYPE_SINK, "SINK", 1, 1, type_sink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 41 */
+	{LDNS_RR_TYPE_OPT, "OPT", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 42 */
+	{LDNS_RR_TYPE_APL, "APL", 0, 0, type_apl_wireformat, LDNS_RDF_TYPE_APL, LDNS_RR_NO_COMPRESS, 0 },
+	/* 43 */
+	{LDNS_RR_TYPE_DS, "DS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 44 */
+	{LDNS_RR_TYPE_SSHFP, "SSHFP", 3, 3, type_sshfp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 45 */
+	{LDNS_RR_TYPE_IPSECKEY, "IPSECKEY", 1, 1, type_ipseckey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 46 */
+	{LDNS_RR_TYPE_RRSIG, "RRSIG", 9, 9, type_rrsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 47 */
+	{LDNS_RR_TYPE_NSEC, "NSEC", 1, 2, type_nsec_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 48 */
+	{LDNS_RR_TYPE_DNSKEY, "DNSKEY", 4, 4, type_dnskey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 49 */
+	{LDNS_RR_TYPE_DHCID, "DHCID", 1, 1, type_dhcid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 50 */
+	{LDNS_RR_TYPE_NSEC3, "NSEC3", 5, 6, type_nsec3_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 51 */
+	{LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 52 */
+	{LDNS_RR_TYPE_TLSA, "TLSA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+{LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+	/* 55
+	 * Hip ends with 0 or more Rendezvous Servers represented as dname's.
+	 * Hence the LDNS_RDF_TYPE_DNAME _variable field and the _maximum field
+	 * set to 0.
+	 */
+	{LDNS_RR_TYPE_HIP, "HIP", 1, 1, type_hip_wireformat, LDNS_RDF_TYPE_DNAME, LDNS_RR_NO_COMPRESS, 0 },
+
+#ifdef RRTYPE_NINFO
+	/* 56 */
+	{LDNS_RR_TYPE_NINFO, "NINFO", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
+#else
+{LDNS_RR_TYPE_NULL, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#endif
+#ifdef RRTYPE_RKEY
+	/* 57 */
+	{LDNS_RR_TYPE_RKEY, "RKEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#else
+{LDNS_RR_TYPE_NULL, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#endif
+	/* 58 */
+	{LDNS_RR_TYPE_TALINK, "TALINK", 2, 2, type_talink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
+
+	/* 59 */
+	{LDNS_RR_TYPE_CDS, "CDS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 60 */
+	{LDNS_RR_TYPE_CDNSKEY, "CDNSKEY", 4, 4, type_dnskey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+#ifdef RRTYPE_OPENPGPKEY
+	/* 61 */
+	{LDNS_RR_TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, type_openpgpkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#else
+{LDNS_RR_TYPE_NULL, "TYPE61", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#endif
+
+{LDNS_RR_TYPE_NULL, "TYPE62", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE69", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE70", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE71", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE72", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE73", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE74", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE75", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE76", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE77", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE78", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE79", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE80", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE81", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE82", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE83", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE84", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE85", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE86", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE87", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE88", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE89", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE90", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE91", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE92", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE93", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE94", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE95", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE96", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE97", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE98", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+	/* 99 */
+	{LDNS_RR_TYPE_SPF,  "SPF", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
+
+	/* UINFO  [IANA-Reserved] */
+{LDNS_RR_TYPE_NULL, "TYPE100", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* UID    [IANA-Reserved] */
+{LDNS_RR_TYPE_NULL, "TYPE101", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* GID    [IANA-Reserved] */
+{LDNS_RR_TYPE_NULL, "TYPE102", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* UNSPEC [IANA-Reserved] */
+{LDNS_RR_TYPE_NULL, "TYPE103", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+	/* 104 */
+	{LDNS_RR_TYPE_NID, "NID", 2, 2, type_nid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 105 */
+	{LDNS_RR_TYPE_L32, "L32", 2, 2, type_l32_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 106 */
+	{LDNS_RR_TYPE_L64, "L64", 2, 2, type_l64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 107 */
+	{LDNS_RR_TYPE_LP, "LP", 2, 2, type_lp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* 108 */
+	{LDNS_RR_TYPE_EUI48, "EUI48", 1, 1, type_eui48_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* 109 */
+	{LDNS_RR_TYPE_EUI64, "EUI64", 1, 1, type_eui64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+{LDNS_RR_TYPE_NULL, "TYPE110", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE111", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE112", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE113", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE114", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE115", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE116", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE117", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE118", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE119", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE120", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE121", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE122", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE123", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE124", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE125", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE126", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE127", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE128", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE129", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE130", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE131", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE132", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE133", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE134", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE135", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE136", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE137", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE138", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE139", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE140", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE141", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE142", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE143", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE144", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE145", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE146", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE147", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE148", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE149", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE150", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE151", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE152", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE153", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE154", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE155", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE156", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE157", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE158", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE159", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE160", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE161", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE162", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE163", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE164", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE165", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE166", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE167", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE168", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE169", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE170", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE171", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE172", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE173", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE174", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE175", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE176", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE177", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE178", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE179", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE180", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE181", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE182", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE183", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE184", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE185", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE186", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE187", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE188", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE189", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE190", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE191", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE192", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE193", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE194", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE195", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE196", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE197", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE198", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE199", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE200", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE201", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE202", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE203", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE204", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE205", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE206", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE207", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE208", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE209", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE210", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE211", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE212", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE213", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE214", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE215", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE216", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE217", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE218", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE219", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE220", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE221", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE222", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE223", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE224", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE225", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE226", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE227", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE228", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE229", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE230", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE231", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE232", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE233", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE234", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE235", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE236", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE237", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE238", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE239", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE240", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE241", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE242", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE243", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE244", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE245", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE246", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+{LDNS_RR_TYPE_NULL, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+	/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
+	 * So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
+	 */
+	/* 249 */
+	{LDNS_RR_TYPE_TKEY, "TKEY", 7, 7, type_tkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+	/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
+	 * So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
+	 */
+	/* 250 */
+	{LDNS_RR_TYPE_TSIG, "TSIG", 7, 7, type_tsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
+
+	/* IXFR: A request for a transfer of an incremental zone transfer */
+{LDNS_RR_TYPE_NULL, "TYPE251", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* AXFR: A request for a transfer of an entire zone */
+{LDNS_RR_TYPE_NULL, "TYPE252", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* MAILB: A request for mailbox-related records (MB, MG or MR) */
+{LDNS_RR_TYPE_NULL, "TYPE253", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* MAILA: A request for mail agent RRs (Obsolete - see MX) */
+{LDNS_RR_TYPE_NULL, "TYPE254", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+	/* ANY: A request for all (available) records */
+{LDNS_RR_TYPE_NULL, "TYPE255", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+#ifdef RRTYPE_URI
+	/* 256 */
+	{LDNS_RR_TYPE_URI, "URI", 3, 3, type_uri_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#else
+{LDNS_RR_TYPE_NULL, "TYPE256", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#endif
+	/* 257 */
+	{LDNS_RR_TYPE_CAA, "CAA", 3, 3, type_caa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+
+/* split in array, no longer contiguous */
+
+#ifdef RRTYPE_TA
+	/* 32768 */
+	{LDNS_RR_TYPE_TA, "TA", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#else
+{LDNS_RR_TYPE_NULL, "TYPE32768", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#endif
+	/* 32769 */
+	{LDNS_RR_TYPE_DLV, "DLV", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }
+};
+/** \endcond */
+
+/**
+ * \def LDNS_RDATA_FIELD_DESCRIPTORS_COUNT
+ * computes the number of rdata fields
+ */
+#define LDNS_RDATA_FIELD_DESCRIPTORS_COUNT \
+	(sizeof(rdata_field_descriptors)/sizeof(rdata_field_descriptors[0]))
+
+
+/*---------------------------------------------------------------------------*
+ * The functions below return an bitmap RDF with the space required to set
+ * or unset all known RR types. Arguably these functions are better situated
+ * in rdata.c, however for the space calculation it is necesarry to walk
+ * through rdata_field_descriptors which is not easily possible from anywhere
+ * other than rr.c where it is declared static.
+ *
+ * Alternatively rr.c could have provided an iterator for rr_type or 
+ * rdf_descriptors, but this seemed overkill for internal use only.
+ */
+static ldns_rr_descriptor* rdata_field_descriptors_end =
+	&rdata_field_descriptors[LDNS_RDATA_FIELD_DESCRIPTORS_COUNT];
+
+/* From RFC3845:
+ *
+ * 2.1.2.  The List of Type Bit Map(s) Field
+ * 
+ *    The RR type space is split into 256 window blocks, each representing
+ *    the low-order 8 bits of the 16-bit RR type space.  Each block that
+ *    has at least one active RR type is encoded using a single octet
+ *    window number (from 0 to 255), a single octet bitmap length (from 1
+ *    to 32) indicating the number of octets used for the window block's
+ *    bitmap, and up to 32 octets (256 bits) of bitmap.
+ * 
+ *    Window blocks are present in the NSEC RR RDATA in increasing
+ *    numerical order.
+ * 
+ *    "|" denotes concatenation
+ * 
+ *    Type Bit Map(s) Field = ( Window Block # | Bitmap Length | Bitmap ) +
+ * 
+ *    <cut>
+ * 
+ *    Blocks with no types present MUST NOT be included.  Trailing zero
+ *    octets in the bitmap MUST be omitted.  The length of each block's
+ *    bitmap is determined by the type code with the largest numerical
+ *    value within that block, among the set of RR types present at the
+ *    NSEC RR's owner name.  Trailing zero octets not specified MUST be
+ *    interpreted as zero octets.
+ */
+static ldns_status
+ldns_rdf_bitmap_known_rr_types_set(ldns_rdf** rdf, int value)
+{
+	uint8_t  window;		/*  most significant octet of type */
+	uint8_t  subtype;		/* least significant octet of type */
+	uint16_t windows[256]		/* Max subtype per window */
+#ifndef S_SPLINT_S
+	                      = { 0 }
+#endif
+	                             ;
+	ldns_rr_descriptor* d;	/* used to traverse rdata_field_descriptors */
+	size_t i;		/* used to traverse windows array */
+
+	size_t sz;			/* size needed for type bitmap rdf */
+	uint8_t* data = NULL;		/* rdf data */
+	uint8_t* dptr;			/* used to itraverse rdf data */
+
+	assert(rdf != NULL);
+
+	/* Which windows need to be in the bitmap rdf?
+	 */
+	for (d=rdata_field_descriptors; d < rdata_field_descriptors_end; d++) {
+		window  = d->_type >> 8;
+		subtype = d->_type & 0xff;
+		if (windows[window] < subtype) {
+			windows[window] = subtype;
+		}
+	}
+
+	/* How much space do we need in the rdf for those windows?
+	 */
+	sz = 0;
+	for (i = 0; i < 256; i++) {
+		if (windows[i]) {
+			sz += windows[i] / 8 + 3;
+		}
+	}
+	if (sz > 0) {
+		/* Format rdf data according RFC3845 Section 2.1.2 (see above)
+		 */
+		dptr = data = LDNS_XMALLOC(uint8_t, sz);
+		memset(data, value, sz);
+		if (!data) {
+			return LDNS_STATUS_MEM_ERR;
+		}
+		for (i = 0; i < 256; i++) {
+			if (windows[i]) {
+				*dptr++ = (uint8_t)i;
+				*dptr++ = (uint8_t)(windows[i] / 8 + 1);
+				dptr += dptr[-1];
+			}
+		}
+	}
+	/* Allocate and return rdf structure for the data
+	 */
+	*rdf = ldns_rdf_new(LDNS_RDF_TYPE_BITMAP, sz, data);
+	if (!*rdf) {
+		LDNS_FREE(data);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_rdf_bitmap_known_rr_types_space(ldns_rdf** rdf)
+{
+	return ldns_rdf_bitmap_known_rr_types_set(rdf, 0);
+}
+
+ldns_status
+ldns_rdf_bitmap_known_rr_types(ldns_rdf** rdf)
+{
+	return ldns_rdf_bitmap_known_rr_types_set(rdf, 255);
+}
+/* End of RDF bitmap functions
+ *---------------------------------------------------------------------------*/
+
+
+const ldns_rr_descriptor *
+ldns_rr_descript(uint16_t type)
+{
+	size_t i;
+	if (type < LDNS_RDATA_FIELD_DESCRIPTORS_COMMON) {
+		return &rdata_field_descriptors[type];
+	} else {
+		/* because not all array index equals type code */
+		for (i = LDNS_RDATA_FIELD_DESCRIPTORS_COMMON;
+		     i < LDNS_RDATA_FIELD_DESCRIPTORS_COUNT;
+		     i++) {
+		        if (rdata_field_descriptors[i]._type == type) {
+		     		return &rdata_field_descriptors[i];
+			}
+		}
+                return &rdata_field_descriptors[0];
+	}
+}
+
+size_t
+ldns_rr_descriptor_minimum(const ldns_rr_descriptor *descriptor)
+{
+	if (descriptor) {
+		return descriptor->_minimum;
+	} else {
+		return 0;
+	}
+}
+
+size_t
+ldns_rr_descriptor_maximum(const ldns_rr_descriptor *descriptor)
+{
+	if (descriptor) {
+		if (descriptor->_variable != LDNS_RDF_TYPE_NONE) {
+			/* Should really be SIZE_MAX... bad FreeBSD.  */
+			return UINT_MAX;
+		} else {
+			return descriptor->_maximum;
+		}
+	} else {
+		return 0;
+	}
+}
+
+ldns_rdf_type
+ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor,
+                              size_t index)
+{
+	assert(descriptor != NULL);
+	assert(index < descriptor->_maximum
+	       || descriptor->_variable != LDNS_RDF_TYPE_NONE);
+	if (index < descriptor->_maximum) {
+		return descriptor->_wireformat[index];
+	} else {
+		return descriptor->_variable;
+	}
+}
+
+ldns_rr_type
+ldns_get_rr_type_by_name(const char *name)
+{
+	unsigned int i;
+	const char *desc_name;
+	const ldns_rr_descriptor *desc;
+
+	/* TYPEXX representation */
+	if (strlen(name) > 4 && strncasecmp(name, "TYPE", 4) == 0) {
+		return atoi(name + 4);
+	}
+
+	/* Normal types */
+	for (i = 0; i < (unsigned int) LDNS_RDATA_FIELD_DESCRIPTORS_COUNT; i++) {
+		desc = &rdata_field_descriptors[i];
+		desc_name = desc->_name;
+		if(desc_name &&
+		   strlen(name) == strlen(desc_name) &&
+		   strncasecmp(name, desc_name, strlen(desc_name)) == 0) {
+			/* because not all array index equals type code */
+			return desc->_type;
+		}
+	}
+
+	/* special cases for query types */
+	if (strlen(name) == 4 && strncasecmp(name, "IXFR", 4) == 0) {
+		return 251;
+	} else if (strlen(name) == 4 && strncasecmp(name, "AXFR", 4) == 0) {
+		return 252;
+	} else if (strlen(name) == 5 && strncasecmp(name, "MAILB", 5) == 0) {
+		return 253;
+	} else if (strlen(name) == 5 && strncasecmp(name, "MAILA", 5) == 0) {
+		return 254;
+	} else if (strlen(name) == 3 && strncasecmp(name, "ANY", 3) == 0) {
+		return 255;
+	}
+
+	return 0;
+}
+
+ldns_rr_class
+ldns_get_rr_class_by_name(const char *name)
+{
+	ldns_lookup_table *lt;
+
+	/* CLASSXX representation */
+	if (strlen(name) > 5 && strncasecmp(name, "CLASS", 5) == 0) {
+		return atoi(name + 5);
+	}
+
+	/* Normal types */
+	lt = ldns_lookup_by_name(ldns_rr_classes, name);
+
+	if (lt) {
+		return lt->id;
+	}
+	return 0;
+}
+
+
+ldns_rr_type
+ldns_rdf2rr_type(const ldns_rdf *rd)
+{
+        ldns_rr_type r;
+
+        if (!rd) {
+                return 0;
+        }
+
+        if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_TYPE) {
+                return 0;
+        }
+
+        r = (ldns_rr_type) ldns_rdf2native_int16(rd);
+        return r;
+}
+
+ldns_rr_type
+ldns_rr_list_type(const ldns_rr_list *rr_list)
+{
+	if (rr_list && ldns_rr_list_rr_count(rr_list) > 0) {
+		return ldns_rr_get_type(ldns_rr_list_rr(rr_list, 0));
+	} else {
+		return 0;
+	}
+}
+
+ldns_rdf *
+ldns_rr_list_owner(const ldns_rr_list *rr_list)
+{
+	if (rr_list && ldns_rr_list_rr_count(rr_list) > 0) {
+		return ldns_rr_owner(ldns_rr_list_rr(rr_list, 0));
+	} else {
+		return NULL;
+	}
+}
diff --git a/ldns/src/rr_functions.c b/ldns/src/rr_functions.c
new file mode 100644
index 0000000..b03751b
--- /dev/null
+++ b/ldns/src/rr_functions.c
@@ -0,0 +1,419 @@
+/*
+ * rr_function.c
+ *
+ * function that operate on specific rr types
+ *
+ * (c) NLnet Labs, 2004-2006
+ * See the file LICENSE for the license
+ */
+
+/*
+ * These come strait from perldoc Net::DNS::RR::xxx
+ * first the read variant, then the write. This is
+ * not complete.
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <limits.h>
+#include <strings.h>
+
+/**
+ * return a specific rdf
+ * \param[in] type type of RR
+ * \param[in] rr   the rr itself
+ * \param[in] pos  at which postion to get it
+ * \return the rdf sought
+ */
+static ldns_rdf *
+ldns_rr_function(ldns_rr_type type, const ldns_rr *rr, size_t pos)
+{
+        if (!rr || ldns_rr_get_type(rr) != type) {
+                return NULL;
+        }
+        return ldns_rr_rdf(rr, pos);
+}
+
+/**
+ * set a specific rdf
+ * \param[in] type type of RR
+ * \param[in] rr   the rr itself
+ * \param[in] rdf  the rdf to set
+ * \param[in] pos  at which postion to set it
+ * \return true or false
+ */
+static bool
+ldns_rr_set_function(ldns_rr_type type, ldns_rr *rr, ldns_rdf *rdf, size_t pos)
+{
+        ldns_rdf *pop;
+        if (!rr || ldns_rr_get_type(rr) != type) {
+                return false;
+        }
+        pop = ldns_rr_set_rdf(rr, rdf, pos);
+ 	ldns_rdf_deep_free(pop);
+        return true;
+}
+
+/* A/AAAA records */
+ldns_rdf *
+ldns_rr_a_address(const ldns_rr *r)
+{
+	/* 2 types to check, cannot use the macro */
+	if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A &&
+			ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) {
+		return NULL;
+	}
+	return ldns_rr_rdf(r, 0);
+}
+
+bool
+ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f)
+{
+	/* 2 types to check, cannot use the macro... */
+	ldns_rdf *pop;
+	if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A &&
+			ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) {
+		return false;
+	}
+	pop = ldns_rr_set_rdf(r, f, 0);
+	if (pop) {
+		LDNS_FREE(pop);
+		return true;
+	} else {
+		return false;
+	}
+}
+
+/* NS record */
+ldns_rdf *
+ldns_rr_ns_nsdname(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_NS, r, 0);
+}
+
+/* MX record */
+ldns_rdf *
+ldns_rr_mx_preference(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_MX, r, 0);
+}
+
+ldns_rdf *
+ldns_rr_mx_exchange(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_MX, r, 1);
+}
+
+/* RRSIG record */
+ldns_rdf *
+ldns_rr_rrsig_typecovered(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 0);
+}
+
+bool
+ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 0);
+}
+
+ldns_rdf *
+ldns_rr_rrsig_algorithm(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 1);
+}
+
+bool
+ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 1);
+}
+
+ldns_rdf *
+ldns_rr_rrsig_labels(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 2);
+}
+
+bool
+ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 2);
+}
+
+ldns_rdf *
+ldns_rr_rrsig_origttl(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 3);
+}
+
+bool
+ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 3);
+}
+
+ldns_rdf *
+ldns_rr_rrsig_expiration(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 4);
+}
+
+bool
+ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 4);
+}
+
+ldns_rdf *
+ldns_rr_rrsig_inception(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 5);
+}
+
+bool
+ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 5);
+}
+
+ldns_rdf *
+ldns_rr_rrsig_keytag(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 6);
+}
+
+bool
+ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 6);
+}
+
+ldns_rdf *
+ldns_rr_rrsig_signame(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 7);
+}
+
+bool
+ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 7);
+}
+
+ldns_rdf *
+ldns_rr_rrsig_sig(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 8);
+}
+
+bool
+ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 8);
+}
+
+/* DNSKEY record */
+ldns_rdf *
+ldns_rr_dnskey_flags(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 0);
+}
+
+bool
+ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 0);
+}
+
+ldns_rdf *
+ldns_rr_dnskey_protocol(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 1);
+}
+
+bool
+ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 1);
+}
+
+ldns_rdf *
+ldns_rr_dnskey_algorithm(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 2);
+}
+
+bool
+ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 2);
+}
+
+ldns_rdf *
+ldns_rr_dnskey_key(const ldns_rr *r)
+{
+	return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 3);
+}
+
+bool
+ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f)
+{
+	return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 3);
+}
+
+size_t
+ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
+                            const size_t len,
+                            const ldns_algorithm alg)
+{
+	/* for DSA keys */
+	uint8_t t;
+	
+	/* for RSA keys */
+	uint16_t exp;
+	uint16_t int16;
+	
+	switch ((ldns_signing_algorithm)alg) {
+	case LDNS_SIGN_DSA:
+	case LDNS_SIGN_DSA_NSEC3:
+		if (len > 0) {
+			t = keydata[0];
+			return (64 + t*8)*8;
+		} else {
+			return 0;
+		}
+		break;
+	case LDNS_SIGN_RSAMD5:
+	case LDNS_SIGN_RSASHA1:
+	case LDNS_SIGN_RSASHA1_NSEC3:
+#ifdef USE_SHA2
+	case LDNS_SIGN_RSASHA256:
+	case LDNS_SIGN_RSASHA512:
+#endif
+		if (len > 0) {
+			if (keydata[0] == 0) {
+				/* big exponent */
+				if (len > 3) {
+					memmove(&int16, keydata + 1, 2);
+					exp = ntohs(int16);
+					return (len - exp - 3)*8;
+				} else {
+					return 0;
+				}
+			} else {
+				exp = keydata[0];
+				return (len-exp-1)*8;
+			}
+		} else {
+			return 0;
+		}
+		break;
+#ifdef USE_GOST
+	case LDNS_SIGN_ECC_GOST:
+		return 512;
+#endif
+#ifdef USE_ECDSA
+        case LDNS_SIGN_ECDSAP256SHA256:
+                return 256;
+        case LDNS_SIGN_ECDSAP384SHA384:
+                return 384;
+#endif
+	case LDNS_SIGN_HMACMD5:
+		return len;
+	default:
+		return 0;
+	}
+}
+
+size_t 
+ldns_rr_dnskey_key_size(const ldns_rr *key) 
+{
+	if (!key || !ldns_rr_dnskey_key(key) 
+			|| !ldns_rr_dnskey_algorithm(key)) {
+		return 0;
+	}
+	return ldns_rr_dnskey_key_size_raw((unsigned char*)ldns_rdf_data(ldns_rr_dnskey_key(key)),
+	                                   ldns_rdf_size(ldns_rr_dnskey_key(key)),
+	                                   ldns_rdf2native_int8(ldns_rr_dnskey_algorithm(key))
+	                                  );
+}
+
+uint32_t ldns_soa_serial_identity(uint32_t ATTR_UNUSED(unused), void *data)
+{
+	return (uint32_t) (intptr_t) data;
+}
+
+uint32_t ldns_soa_serial_increment(uint32_t s, void *ATTR_UNUSED(unused))
+{
+	return ldns_soa_serial_increment_by(s, (void *)1);
+}
+
+uint32_t ldns_soa_serial_increment_by(uint32_t s, void *data)
+{
+	return s + (intptr_t) data;
+}
+
+uint32_t ldns_soa_serial_datecounter(uint32_t s, void *data)
+{
+	struct tm tm;
+	char s_str[11];
+	int32_t new_s;
+	time_t t = data ? (time_t) (intptr_t) data : ldns_time(NULL);
+
+	(void) strftime(s_str, 11, "%Y%m%d00", localtime_r(&t, &tm));
+	new_s = (int32_t) atoi(s_str);
+	return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s);
+}
+
+uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data)
+{
+	int32_t new_s = data ? (int32_t) (intptr_t) data 
+			     : (int32_t) ldns_time(NULL);
+	return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s);
+}
+
+void
+ldns_rr_soa_increment(ldns_rr *soa)
+{
+	ldns_rr_soa_increment_func_data(soa, ldns_soa_serial_increment, NULL);
+}
+
+void
+ldns_rr_soa_increment_func(ldns_rr *soa, ldns_soa_serial_increment_func_t f)
+{
+	ldns_rr_soa_increment_func_data(soa, f, NULL);
+}
+
+void
+ldns_rr_soa_increment_func_data(ldns_rr *soa, 
+		ldns_soa_serial_increment_func_t f, void *data)
+{
+	ldns_rdf *prev_soa_serial_rdf;
+	if ( !soa || !f || ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA 
+			|| !ldns_rr_rdf(soa, 2)) {
+		return;
+	}
+	prev_soa_serial_rdf = ldns_rr_set_rdf(
+		  soa
+		, ldns_native2rdf_int32(
+			  LDNS_RDF_TYPE_INT32
+			, (*f)( ldns_rdf2native_int32(
+					ldns_rr_rdf(soa, 2))
+			      , data
+			)
+		)
+		, 2
+	);
+	LDNS_FREE(prev_soa_serial_rdf);
+}
+
+void
+ldns_rr_soa_increment_func_int(ldns_rr *soa, 
+		ldns_soa_serial_increment_func_t f, int data)
+{
+	ldns_rr_soa_increment_func_data(soa, f, (void *) (intptr_t) data);
+}
+
diff --git a/ldns/src/sha1.c b/ldns/src/sha1.c
new file mode 100644
index 0000000..18a4dd2
--- /dev/null
+++ b/ldns/src/sha1.c
@@ -0,0 +1,177 @@
+/*
+ * modified for ldns by Jelte Jansen, original taken from OpenBSD:
+ * 
+ * SHA-1 in C
+ * By Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ * 
+ * Test Vectors (from FIPS PUB 180-1)
+ * "abc"
+ *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ * A million repetitions of "a"
+ *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
+
+#include <ldns/config.h>
+#include <ldns/ldns.h>
+#include <strings.h>
+
+#define SHA1HANDSOFF 1 /* Copies data before messing with it. */
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void
+ldns_sha1_transform(uint32_t state[5], const unsigned char buffer[LDNS_SHA1_BLOCK_LENGTH])
+{
+    uint32_t a, b, c, d, e;
+    typedef union {
+        unsigned char c[64];
+        unsigned int l[16];
+    } CHAR64LONG16;
+    CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+    unsigned char workspace[LDNS_SHA1_BLOCK_LENGTH];
+
+    block = (CHAR64LONG16 *)workspace;
+    memmove(block, buffer, LDNS_SHA1_BLOCK_LENGTH);
+#else
+    block = (CHAR64LONG16 *)buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void
+ldns_sha1_init(ldns_sha1_ctx *context)
+{
+    /* SHA1 initialization constants */
+    context->count = 0;
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+}
+
+
+/* Run your data through this. */
+
+void
+ldns_sha1_update(ldns_sha1_ctx *context, const unsigned char *data, unsigned int len)
+{
+    unsigned int i;
+    unsigned int j;
+
+    j = (unsigned)(uint32_t)((context->count >> 3) & 63);
+    context->count += (len << 3);
+    if ((j + len) > 63) {
+        memmove(&context->buffer[j], data, (i = 64 - j));
+        ldns_sha1_transform(context->state, context->buffer);
+        for ( ; i + 63 < len; i += 64) {
+            ldns_sha1_transform(context->state, &data[i]);
+        }
+        j = 0;
+    }
+    else i = 0;
+    memmove(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void
+ldns_sha1_final(unsigned char digest[LDNS_SHA1_DIGEST_LENGTH], ldns_sha1_ctx *context)
+{
+    unsigned int i;
+    unsigned char finalcount[8];
+
+    for (i = 0; i < 8; i++) {
+        finalcount[i] = (unsigned char)((context->count >>
+            ((7 - (i & 7)) * 8)) & 255);  /* Endian independent */
+    }
+    ldns_sha1_update(context, (unsigned char *)"\200", 1);
+    while ((context->count & 504) != 448) {
+        ldns_sha1_update(context, (unsigned char *)"\0", 1);
+    }
+    ldns_sha1_update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+
+    if (digest != NULL)
+        for (i = 0; i < LDNS_SHA1_DIGEST_LENGTH; i++) {
+            digest[i] = (unsigned char)((context->state[i >> 2] >>
+                ((3 - (i & 3)) * 8)) & 255);
+      }
+#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite its own static vars */
+    ldns_sha1_transform(context->state, context->buffer);
+#endif
+}
+
+unsigned char *
+ldns_sha1(unsigned char *data, unsigned int data_len, unsigned char *digest)
+{
+    ldns_sha1_ctx ctx;
+    ldns_sha1_init(&ctx);
+    ldns_sha1_update(&ctx, data, data_len);
+    ldns_sha1_final(digest, &ctx);
+    return digest;
+}
diff --git a/ldns/src/sha2.c b/ldns/src/sha2.c
new file mode 100644
index 0000000..9a27122
--- /dev/null
+++ b/ldns/src/sha2.c
@@ -0,0 +1,991 @@
+/*
+ * FILE:	sha2.c
+ * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
+ * 
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Modified by Jelte Jansen to fit in ldns, and not clash with any
+ * system-defined SHA code.
+ * Changes:
+ * - Renamed (external) functions and constants to fit ldns style
+ * - Removed _End and _Data functions
+ * - Added ldns_shaX(data, len, digest) convenience functions
+ * - Removed prototypes of _Transform functions and made those static
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
+ */
+
+#include <ldns/config.h>
+#include <string.h>	/* memcpy()/memset() or bcopy()/bzero() */
+#include <assert.h>	/* assert() */
+#include <ldns/sha2.h>
+
+/*
+ * ASSERT NOTE:
+ * Some sanity checking code is included using assert().  On my FreeBSD
+ * system, this additional code can be removed by compiling with NDEBUG
+ * defined.  Check your own systems manpage on assert() to see how to
+ * compile WITHOUT the sanity checking code on your system.
+ *
+ * UNROLLED TRANSFORM LOOP NOTE:
+ * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
+ * loop version for the hash transform rounds (defined using macros
+ * later in this file).  Either define on the command line, for example:
+ *
+ *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
+ *
+ * or define below:
+ *
+ *   #define SHA2_UNROLL_TRANSFORM
+ *
+ */
+
+
+/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+/*
+ * BYTE_ORDER NOTE:
+ *
+ * Please make sure that your system defines BYTE_ORDER.  If your
+ * architecture is little-endian, make sure it also defines
+ * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
+ * equivilent.
+ *
+ * If your system does not define the above, then you can do so by
+ * hand like this:
+ *
+ *   #define LITTLE_ENDIAN 1234
+ *   #define BIG_ENDIAN    4321
+ *
+ * And for little-endian machines, add:
+ *
+ *   #define BYTE_ORDER LITTLE_ENDIAN 
+ *
+ * Or for big-endian machines:
+ *
+ *   #define BYTE_ORDER BIG_ENDIAN
+ *
+ * The FreeBSD machine this was written on defines BYTE_ORDER
+ * appropriately by including <sys/types.h> (which in turn includes
+ * <machine/endian.h> where the appropriate definitions are actually
+ * made).
+ */
+#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
+#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+#endif
+
+typedef uint8_t  sha2_byte;	/* Exactly 1 byte */
+typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
+#ifdef S_SPLINT_S
+typedef unsigned long long sha2_word64; /* lint 8 bytes */
+#else
+typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
+#endif
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+/* NOTE: Most of these are in sha2.h */
+#define ldns_sha256_SHORT_BLOCK_LENGTH	(LDNS_SHA256_BLOCK_LENGTH - 8)
+#define ldns_sha384_SHORT_BLOCK_LENGTH	(LDNS_SHA384_BLOCK_LENGTH - 16)
+#define ldns_sha512_SHORT_BLOCK_LENGTH	(LDNS_SHA512_BLOCK_LENGTH - 16)
+
+
+/*** ENDIAN REVERSAL MACROS *******************************************/
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define REVERSE32(w,x)	{ \
+	sha2_word32 tmp = (w); \
+	tmp = (tmp >> 16) | (tmp << 16); \
+	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
+}
+#ifndef S_SPLINT_S
+#define REVERSE64(w,x)	{ \
+	sha2_word64 tmp = (w); \
+	tmp = (tmp >> 32) | (tmp << 32); \
+	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
+	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
+	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
+	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
+}
+#else /* splint */
+#define REVERSE64(w,x) /* splint */
+#endif /* splint */
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n)	{ \
+	(w)[0] += (sha2_word64)(n); \
+	if ((w)[0] < (n)) { \
+		(w)[1]++; \
+	} \
+}
+#ifdef S_SPLINT_S
+#undef ADDINC128
+#define ADDINC128(w,n) /* splint */
+#endif
+
+/*
+ * Macros for copying blocks of memory and for zeroing out ranges
+ * of memory.  Using these macros makes it easy to switch from
+ * using memset()/memcpy() and using bzero()/bcopy().
+ *
+ * Please define either SHA2_USE_MEMSET_MEMCPY or define
+ * SHA2_USE_BZERO_BCOPY depending on which function set you
+ * choose to use:
+ */
+#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
+/* Default to memset()/memcpy() if no option is specified */
+#define	SHA2_USE_MEMSET_MEMCPY	1
+#endif
+#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
+/* Abort with an error if BOTH options are defined */
+#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
+#endif
+
+#ifdef SHA2_USE_MEMSET_MEMCPY
+#define MEMSET_BZERO(p,l)	memset((p), 0, (l))
+#define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
+#endif
+#ifdef SHA2_USE_BZERO_BCOPY
+#define MEMSET_BZERO(p,l)	bzero((p), (l))
+#define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
+#endif
+
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
+ *   S is a ROTATION) because the SHA-256/384/512 description document
+ *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
+ *   same "backwards" definition.
+ */
+/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
+#define R(b,x) 		((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-256): */
+#define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
+
+/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Four of six logical functions used in SHA-256: */
+#define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
+#define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
+#define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
+#define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
+#define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-256: */
+static const sha2_word32 K256[64] = {
+	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* initial hash value H for SHA-256: */
+static const sha2_word32 ldns_sha256_initial_hash_value[8] = {
+	0x6a09e667UL,
+	0xbb67ae85UL,
+	0x3c6ef372UL,
+	0xa54ff53aUL,
+	0x510e527fUL,
+	0x9b05688cUL,
+	0x1f83d9abUL,
+	0x5be0cd19UL
+};
+
+/* Hash constant words K for SHA-384 and SHA-512: */
+static const sha2_word64 K512[80] = {
+	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+/* initial hash value H for SHA-384 */
+static const sha2_word64 sha384_initial_hash_value[8] = {
+	0xcbbb9d5dc1059ed8ULL,
+	0x629a292a367cd507ULL,
+	0x9159015a3070dd17ULL,
+	0x152fecd8f70e5939ULL,
+	0x67332667ffc00b31ULL,
+	0x8eb44a8768581511ULL,
+	0xdb0c2e0d64f98fa7ULL,
+	0x47b5481dbefa4fa4ULL
+};
+
+/* initial hash value H for SHA-512 */
+static const sha2_word64 sha512_initial_hash_value[8] = {
+	0x6a09e667f3bcc908ULL,
+	0xbb67ae8584caa73bULL,
+	0x3c6ef372fe94f82bULL,
+	0xa54ff53a5f1d36f1ULL,
+	0x510e527fade682d1ULL,
+	0x9b05688c2b3e6c1fULL,
+	0x1f83d9abfb41bd6bULL,
+	0x5be0cd19137e2179ULL
+};
+
+/*** SHA-256: *********************************************************/
+void ldns_sha256_init(ldns_sha256_CTX* context) {
+	if (context == (ldns_sha256_CTX*)0) {
+		return;
+	}
+	MEMCPY_BCOPY(context->state, ldns_sha256_initial_hash_value, LDNS_SHA256_DIGEST_LENGTH);
+	MEMSET_BZERO(context->buffer, LDNS_SHA256_BLOCK_LENGTH);
+	context->bitcount = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
+	REVERSE32(*data++, W256[j]); \
+	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+             K256[j] + W256[j]; \
+	(d) += T1; \
+	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+	j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
+	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+	     K256[j] + (W256[j] = *data++); \
+	(d) += T1; \
+	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+	j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256(a,b,c,d,e,f,g,h)	\
+	s0 = W256[(j+1)&0x0f]; \
+	s0 = sigma0_256(s0); \
+	s1 = W256[(j+14)&0x0f]; \
+	s1 = sigma1_256(s1); \
+	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
+	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
+	(d) += T1; \
+	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+	j++
+
+static void ldns_sha256_Transform(ldns_sha256_CTX* context,
+                                  const sha2_word32* data) {
+	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
+	sha2_word32	T1, *W256;
+	int		j;
+
+	W256 = (sha2_word32*)context->buffer;
+
+	/* initialize registers with the prev. intermediate value */
+	a = context->state[0];
+	b = context->state[1];
+	c = context->state[2];
+	d = context->state[3];
+	e = context->state[4];
+	f = context->state[5];
+	g = context->state[6];
+	h = context->state[7];
+
+	j = 0;
+	do {
+		/* Rounds 0 to 15 (unrolled): */
+		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
+		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
+		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
+		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
+		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
+		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
+		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
+		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
+	} while (j < 16);
+
+	/* Now for the remaining rounds to 64: */
+	do {
+		ROUND256(a,b,c,d,e,f,g,h);
+		ROUND256(h,a,b,c,d,e,f,g);
+		ROUND256(g,h,a,b,c,d,e,f);
+		ROUND256(f,g,h,a,b,c,d,e);
+		ROUND256(e,f,g,h,a,b,c,d);
+		ROUND256(d,e,f,g,h,a,b,c);
+		ROUND256(c,d,e,f,g,h,a,b);
+		ROUND256(b,c,d,e,f,g,h,a);
+	} while (j < 64);
+
+	/* Compute the current intermediate hash value */
+	context->state[0] += a;
+	context->state[1] += b;
+	context->state[2] += c;
+	context->state[3] += d;
+	context->state[4] += e;
+	context->state[5] += f;
+	context->state[6] += g;
+	context->state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+static void ldns_sha256_Transform(ldns_sha256_CTX* context,
+                                  const sha2_word32* data) {
+	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
+	sha2_word32	T1, T2, *W256;
+	int		j;
+
+	W256 = (sha2_word32*)context->buffer;
+
+	/* initialize registers with the prev. intermediate value */
+	a = context->state[0];
+	b = context->state[1];
+	c = context->state[2];
+	d = context->state[3];
+	e = context->state[4];
+	f = context->state[5];
+	g = context->state[6];
+	h = context->state[7];
+
+	j = 0;
+	do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+		/* Copy data while converting to host byte order */
+		REVERSE32(*data++,W256[j]);
+		/* Apply the SHA-256 compression function to update a..h */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+		/* Apply the SHA-256 compression function to update a..h with copy */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+		T2 = Sigma0_256(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 16);
+
+	do {
+		/* Part of the message block expansion: */
+		s0 = W256[(j+1)&0x0f];
+		s0 = sigma0_256(s0);
+		s1 = W256[(j+14)&0x0f];	
+		s1 = sigma1_256(s1);
+
+		/* Apply the SHA-256 compression function to update a..h */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 
+		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
+		T2 = Sigma0_256(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 64);
+
+	/* Compute the current intermediate hash value */
+	context->state[0] += a;
+	context->state[1] += b;
+	context->state[2] += c;
+	context->state[3] += d;
+	context->state[4] += e;
+	context->state[5] += f;
+	context->state[6] += g;
+	context->state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void ldns_sha256_update(ldns_sha256_CTX* context, const sha2_byte *data, size_t len) {
+	size_t freespace, usedspace;
+
+	if (len == 0) {
+		/* Calling with no data is valid - we do nothing */
+		return;
+	}
+
+	/* Sanity check: */
+	assert(context != (ldns_sha256_CTX*)0 && data != (sha2_byte*)0);
+
+	usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH;
+	if (usedspace > 0) {
+		/* Calculate how much free space is available in the buffer */
+		freespace = LDNS_SHA256_BLOCK_LENGTH - usedspace;
+
+		if (len >= freespace) {
+			/* Fill the buffer completely and process it */
+			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+			context->bitcount += freespace << 3;
+			len -= freespace;
+			data += freespace;
+			ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
+		} else {
+			/* The buffer is not yet full */
+			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+			context->bitcount += len << 3;
+			/* Clean up: */
+			usedspace = freespace = 0;
+			return;
+		}
+	}
+	while (len >= LDNS_SHA256_BLOCK_LENGTH) {
+		/* Process as many complete blocks as we can */
+		ldns_sha256_Transform(context, (sha2_word32*)data);
+		context->bitcount += LDNS_SHA256_BLOCK_LENGTH << 3;
+		len -= LDNS_SHA256_BLOCK_LENGTH;
+		data += LDNS_SHA256_BLOCK_LENGTH;
+	}
+	if (len > 0) {
+		/* There's left-overs, so save 'em */
+		MEMCPY_BCOPY(context->buffer, data, len);
+		context->bitcount += len << 3;
+	}
+	/* Clean up: */
+	usedspace = freespace = 0;
+}
+
+typedef union _ldns_sha2_buffer_union {
+        uint8_t*  theChars;
+        uint64_t* theLongs;
+} ldns_sha2_buffer_union;
+
+void ldns_sha256_final(sha2_byte digest[], ldns_sha256_CTX* context) {
+	sha2_word32	*d = (sha2_word32*)digest;
+	size_t usedspace;
+	ldns_sha2_buffer_union cast_var;
+
+	/* Sanity check: */
+	assert(context != (ldns_sha256_CTX*)0);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != (sha2_byte*)0) {
+		usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+		/* Convert FROM host byte order */
+		REVERSE64(context->bitcount,context->bitcount);
+#endif
+		if (usedspace > 0) {
+			/* Begin padding with a 1 bit: */
+			context->buffer[usedspace++] = 0x80;
+
+			if (usedspace <= ldns_sha256_SHORT_BLOCK_LENGTH) {
+				/* Set-up for the last transform: */
+				MEMSET_BZERO(&context->buffer[usedspace], ldns_sha256_SHORT_BLOCK_LENGTH - usedspace);
+			} else {
+				if (usedspace < LDNS_SHA256_BLOCK_LENGTH) {
+					MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA256_BLOCK_LENGTH - usedspace);
+				}
+				/* Do second-to-last transform: */
+				ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
+
+				/* And set-up for the last transform: */
+				MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH);
+			}
+		} else {
+			/* Set-up for the last transform: */
+			MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH);
+
+			/* Begin padding with a 1 bit: */
+			*context->buffer = 0x80;
+		}
+		/* Set the bit count: */
+		cast_var.theChars = context->buffer;
+		cast_var.theLongs[ldns_sha256_SHORT_BLOCK_LENGTH / 8] = context->bitcount;
+
+		/* final transform: */
+		ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+		{
+			/* Convert TO host byte order */
+			int	j;
+			for (j = 0; j < 8; j++) {
+				REVERSE32(context->state[j],context->state[j]);
+				*d++ = context->state[j];
+			}
+		}
+#else
+		MEMCPY_BCOPY(d, context->state, LDNS_SHA256_DIGEST_LENGTH);
+#endif
+	}
+
+	/* Clean up state data: */
+	MEMSET_BZERO(context, sizeof(ldns_sha256_CTX));
+	usedspace = 0;
+}
+
+unsigned char *
+ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest)
+{
+    ldns_sha256_CTX ctx;
+    ldns_sha256_init(&ctx);
+    ldns_sha256_update(&ctx, data, data_len);
+    ldns_sha256_final(digest, &ctx);
+    return digest;
+}
+
+/*** SHA-512: *********************************************************/
+void ldns_sha512_init(ldns_sha512_CTX* context) {
+	if (context == (ldns_sha512_CTX*)0) {
+		return;
+	}
+	MEMCPY_BCOPY(context->state, sha512_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH);
+	MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH);
+	context->bitcount[0] = context->bitcount[1] =  0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
+	REVERSE64(*data++, W512[j]); \
+	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+             K512[j] + W512[j]; \
+	(d) += T1, \
+	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
+	j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
+	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+             K512[j] + (W512[j] = *data++); \
+	(d) += T1; \
+	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+	j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512(a,b,c,d,e,f,g,h)	\
+	s0 = W512[(j+1)&0x0f]; \
+	s0 = sigma0_512(s0); \
+	s1 = W512[(j+14)&0x0f]; \
+	s1 = sigma1_512(s1); \
+	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
+             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
+	(d) += T1; \
+	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+	j++
+
+static void ldns_sha512_Transform(ldns_sha512_CTX* context,
+                                  const sha2_word64* data) {
+	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
+	sha2_word64	T1, *W512 = (sha2_word64*)context->buffer;
+	int		j;
+
+	/* initialize registers with the prev. intermediate value */
+	a = context->state[0];
+	b = context->state[1];
+	c = context->state[2];
+	d = context->state[3];
+	e = context->state[4];
+	f = context->state[5];
+	g = context->state[6];
+	h = context->state[7];
+
+	j = 0;
+	do {
+		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
+		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
+		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
+		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
+		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
+		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
+		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
+		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
+	} while (j < 16);
+
+	/* Now for the remaining rounds up to 79: */
+	do {
+		ROUND512(a,b,c,d,e,f,g,h);
+		ROUND512(h,a,b,c,d,e,f,g);
+		ROUND512(g,h,a,b,c,d,e,f);
+		ROUND512(f,g,h,a,b,c,d,e);
+		ROUND512(e,f,g,h,a,b,c,d);
+		ROUND512(d,e,f,g,h,a,b,c);
+		ROUND512(c,d,e,f,g,h,a,b);
+		ROUND512(b,c,d,e,f,g,h,a);
+	} while (j < 80);
+
+	/* Compute the current intermediate hash value */
+	context->state[0] += a;
+	context->state[1] += b;
+	context->state[2] += c;
+	context->state[3] += d;
+	context->state[4] += e;
+	context->state[5] += f;
+	context->state[6] += g;
+	context->state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+static void ldns_sha512_Transform(ldns_sha512_CTX* context,
+                                  const sha2_word64* data) {
+	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
+	sha2_word64	T1, T2, *W512 = (sha2_word64*)context->buffer;
+	int		j;
+
+	/* initialize registers with the prev. intermediate value */
+	a = context->state[0];
+	b = context->state[1];
+	c = context->state[2];
+	d = context->state[3];
+	e = context->state[4];
+	f = context->state[5];
+	g = context->state[6];
+	h = context->state[7];
+
+	j = 0;
+	do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+		/* Convert TO host byte order */
+		REVERSE64(*data++, W512[j]);
+		/* Apply the SHA-512 compression function to update a..h */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+		/* Apply the SHA-512 compression function to update a..h with copy */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+		T2 = Sigma0_512(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 16);
+
+	do {
+		/* Part of the message block expansion: */
+		s0 = W512[(j+1)&0x0f];
+		s0 = sigma0_512(s0);
+		s1 = W512[(j+14)&0x0f];
+		s1 =  sigma1_512(s1);
+
+		/* Apply the SHA-512 compression function to update a..h */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+		T2 = Sigma0_512(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 80);
+
+	/* Compute the current intermediate hash value */
+	context->state[0] += a;
+	context->state[1] += b;
+	context->state[2] += c;
+	context->state[3] += d;
+	context->state[4] += e;
+	context->state[5] += f;
+	context->state[6] += g;
+	context->state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void ldns_sha512_update(ldns_sha512_CTX* context, const sha2_byte *data, size_t len) {
+	size_t freespace, usedspace;
+
+	if (len == 0) {
+		/* Calling with no data is valid - we do nothing */
+		return;
+	}
+
+	/* Sanity check: */
+	assert(context != (ldns_sha512_CTX*)0 && data != (sha2_byte*)0);
+
+	usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH;
+	if (usedspace > 0) {
+		/* Calculate how much free space is available in the buffer */
+		freespace = LDNS_SHA512_BLOCK_LENGTH - usedspace;
+
+		if (len >= freespace) {
+			/* Fill the buffer completely and process it */
+			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+			ADDINC128(context->bitcount, freespace << 3);
+			len -= freespace;
+			data += freespace;
+			ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
+		} else {
+			/* The buffer is not yet full */
+			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+			ADDINC128(context->bitcount, len << 3);
+			/* Clean up: */
+			usedspace = freespace = 0;
+			return;
+		}
+	}
+	while (len >= LDNS_SHA512_BLOCK_LENGTH) {
+		/* Process as many complete blocks as we can */
+		ldns_sha512_Transform(context, (sha2_word64*)data);
+		ADDINC128(context->bitcount, LDNS_SHA512_BLOCK_LENGTH << 3);
+		len -= LDNS_SHA512_BLOCK_LENGTH;
+		data += LDNS_SHA512_BLOCK_LENGTH;
+	}
+	if (len > 0) {
+		/* There's left-overs, so save 'em */
+		MEMCPY_BCOPY(context->buffer, data, len);
+		ADDINC128(context->bitcount, len << 3);
+	}
+	/* Clean up: */
+	usedspace = freespace = 0;
+}
+
+static void ldns_sha512_Last(ldns_sha512_CTX* context) {
+	size_t usedspace;
+	ldns_sha2_buffer_union cast_var;
+
+	usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+	/* Convert FROM host byte order */
+	REVERSE64(context->bitcount[0],context->bitcount[0]);
+	REVERSE64(context->bitcount[1],context->bitcount[1]);
+#endif
+	if (usedspace > 0) {
+		/* Begin padding with a 1 bit: */
+		context->buffer[usedspace++] = 0x80;
+
+		if (usedspace <= ldns_sha512_SHORT_BLOCK_LENGTH) {
+			/* Set-up for the last transform: */
+			MEMSET_BZERO(&context->buffer[usedspace], ldns_sha512_SHORT_BLOCK_LENGTH - usedspace);
+		} else {
+			if (usedspace < LDNS_SHA512_BLOCK_LENGTH) {
+				MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA512_BLOCK_LENGTH - usedspace);
+			}
+			/* Do second-to-last transform: */
+			ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
+
+			/* And set-up for the last transform: */
+			MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH - 2);
+		}
+	} else {
+		/* Prepare for final transform: */
+		MEMSET_BZERO(context->buffer, ldns_sha512_SHORT_BLOCK_LENGTH);
+
+		/* Begin padding with a 1 bit: */
+		*context->buffer = 0x80;
+	}
+	/* Store the length of input data (in bits): */
+	cast_var.theChars = context->buffer;
+	cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8] = context->bitcount[1];
+	cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8 + 1] = context->bitcount[0];
+
+	/* final transform: */
+	ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
+}
+
+void ldns_sha512_final(sha2_byte digest[], ldns_sha512_CTX* context) {
+	sha2_word64	*d = (sha2_word64*)digest;
+
+	/* Sanity check: */
+	assert(context != (ldns_sha512_CTX*)0);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != (sha2_byte*)0) {
+		ldns_sha512_Last(context);
+
+		/* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+		{
+			/* Convert TO host byte order */
+			int	j;
+			for (j = 0; j < 8; j++) {
+				REVERSE64(context->state[j],context->state[j]);
+				*d++ = context->state[j];
+			}
+		}
+#else
+		MEMCPY_BCOPY(d, context->state, LDNS_SHA512_DIGEST_LENGTH);
+#endif
+	}
+
+	/* Zero out state data */
+	MEMSET_BZERO(context, sizeof(ldns_sha512_CTX));
+}
+
+unsigned char *
+ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest)
+{
+    ldns_sha512_CTX ctx;
+    ldns_sha512_init(&ctx);
+    ldns_sha512_update(&ctx, data, data_len);
+    ldns_sha512_final(digest, &ctx);
+    return digest;
+}
+
+/*** SHA-384: *********************************************************/
+void ldns_sha384_init(ldns_sha384_CTX* context) {
+	if (context == (ldns_sha384_CTX*)0) {
+		return;
+	}
+	MEMCPY_BCOPY(context->state, sha384_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH);
+	MEMSET_BZERO(context->buffer, LDNS_SHA384_BLOCK_LENGTH);
+	context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+void ldns_sha384_update(ldns_sha384_CTX* context, const sha2_byte* data, size_t len) {
+	ldns_sha512_update((ldns_sha512_CTX*)context, data, len);
+}
+
+void ldns_sha384_final(sha2_byte digest[], ldns_sha384_CTX* context) {
+	sha2_word64	*d = (sha2_word64*)digest;
+
+	/* Sanity check: */
+	assert(context != (ldns_sha384_CTX*)0);
+
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != (sha2_byte*)0) {
+		ldns_sha512_Last((ldns_sha512_CTX*)context);
+
+		/* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+		{
+			/* Convert TO host byte order */
+			int	j;
+			for (j = 0; j < 6; j++) {
+				REVERSE64(context->state[j],context->state[j]);
+				*d++ = context->state[j];
+			}
+		}
+#else
+		MEMCPY_BCOPY(d, context->state, LDNS_SHA384_DIGEST_LENGTH);
+#endif
+	}
+
+	/* Zero out state data */
+	MEMSET_BZERO(context, sizeof(ldns_sha384_CTX));
+}
+
+unsigned char *
+ldns_sha384(unsigned char *data, unsigned int data_len, unsigned char *digest)
+{
+    ldns_sha384_CTX ctx;
+    ldns_sha384_init(&ctx);
+    ldns_sha384_update(&ctx, data, data_len);
+    ldns_sha384_final(digest, &ctx);
+    return digest;
+}
diff --git a/ldns/src/str2host.c b/ldns/src/str2host.c
new file mode 100644
index 0000000..cd07c89
--- /dev/null
+++ b/ldns/src/str2host.c
@@ -0,0 +1,1604 @@
+/*
+ * str2host.c
+ *
+ * conversion routines from the presentation format
+ * to the host format
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <time.h>
+
+#include <errno.h>
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <limits.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+ldns_status
+ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
+{
+	char *end = NULL;
+	uint16_t *r;
+	r = LDNS_MALLOC(uint16_t);
+        if(!r) return LDNS_STATUS_MEM_ERR;
+
+	*r = htons((uint16_t)strtol((char *)shortstr, &end, 10));
+
+	if(*end != 0) {
+		LDNS_FREE(r);
+		return LDNS_STATUS_INVALID_INT;
+	} else {
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_INT16, sizeof(uint16_t), r);
+		LDNS_FREE(r);
+		return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+	}
+}
+
+ldns_status
+ldns_str2rdf_time(ldns_rdf **rd, const char *time)
+{
+	/* convert a time YYYYDDMMHHMMSS to wireformat */
+	uint16_t *r = NULL;
+	struct tm tm;
+	uint32_t l;
+	char *end;
+
+	/* Try to scan the time... */
+	r = (uint16_t*)LDNS_MALLOC(uint32_t);
+        if(!r) return LDNS_STATUS_MEM_ERR;
+
+	memset(&tm, 0, sizeof(tm));
+
+	if (strlen(time) == 14 &&
+	    sscanf(time, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6
+	   ) {
+	   	tm.tm_year -= 1900;
+	   	tm.tm_mon--;
+	   	/* Check values */
+		if (tm.tm_year < 70) {
+			goto bad_format;
+		}
+		if (tm.tm_mon < 0 || tm.tm_mon > 11) {
+			goto bad_format;
+		}
+		if (tm.tm_mday < 1 || tm.tm_mday > 31) {
+			goto bad_format;
+		}
+
+		if (tm.tm_hour < 0 || tm.tm_hour > 23) {
+			goto bad_format;
+		}
+
+		if (tm.tm_min < 0 || tm.tm_min > 59) {
+			goto bad_format;
+		}
+
+		if (tm.tm_sec < 0 || tm.tm_sec > 59) {
+			goto bad_format;
+		}
+
+		l = htonl(ldns_mktime_from_utc(&tm));
+		memcpy(r, &l, sizeof(uint32_t));
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_TIME, sizeof(uint32_t), r);
+		LDNS_FREE(r);
+		return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+	} else {
+		/* handle it as 32 bits timestamp */
+		l = htonl((uint32_t)strtol((char*)time, &end, 10));
+		if(*end != 0) {
+			LDNS_FREE(r);
+			return LDNS_STATUS_ERR;
+		} else {
+			memcpy(r, &l, sizeof(uint32_t));
+			*rd = ldns_rdf_new_frm_data(
+				LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
+			LDNS_FREE(r);
+		        return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+		}
+	}
+
+	bad_format:
+	LDNS_FREE(r);
+	return LDNS_STATUS_INVALID_TIME;
+}
+
+ldns_status
+ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
+{
+	uint8_t salt_length;
+	int c;
+	int salt_length_str;
+
+	uint8_t *salt;
+	uint8_t *data;
+	if(rd == NULL) {
+		return LDNS_STATUS_NULL;
+	}
+
+	salt_length_str = (int)strlen(salt_str);
+	if (salt_length_str == 1 && salt_str[0] == '-') {
+		salt_length_str = 0;
+	} else if (salt_length_str % 2 != 0) {
+		return LDNS_STATUS_INVALID_HEX;
+	}
+	if (salt_length_str > 512) {
+		return LDNS_STATUS_INVALID_HEX;
+	}
+
+	salt = LDNS_XMALLOC(uint8_t, salt_length_str / 2);
+        if(!salt) {
+                return LDNS_STATUS_MEM_ERR;
+        }
+	for (c = 0; c < salt_length_str; c += 2) {
+		if (isxdigit((int) salt_str[c]) && isxdigit((int) salt_str[c+1])) {
+			salt[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 +
+					  ldns_hexdigit_to_int(salt_str[c+1]);
+		} else {
+			LDNS_FREE(salt);
+			return LDNS_STATUS_INVALID_HEX;
+		}
+	}
+	salt_length = (uint8_t) (salt_length_str / 2);
+
+	data = LDNS_XMALLOC(uint8_t, 1 + salt_length);
+        if(!data) {
+	        LDNS_FREE(salt);
+                return LDNS_STATUS_MEM_ERR;
+        }
+	data[0] = salt_length;
+	memcpy(&data[1], salt, salt_length);
+	*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT, 1 + salt_length, data);
+	LDNS_FREE(data);
+	LDNS_FREE(salt);
+
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_period(ldns_rdf **rd,const char *period)
+{
+        uint32_t p;
+        const char *end;
+
+        /* Allocate required space... */
+        p = ldns_str2period(period, &end);
+
+        if (*end != 0) {
+		return LDNS_STATUS_ERR;
+        } else {
+                p = (uint32_t) htonl(p);
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_PERIOD, sizeof(uint32_t), &p);
+        }
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
+{
+	char *end;
+	uint16_t *r = NULL;
+	uint32_t l;
+
+	r = (uint16_t*)LDNS_MALLOC(uint32_t);
+        if(!r) return LDNS_STATUS_MEM_ERR;
+	errno = 0; /* must set to zero before call,
+			note race condition on errno */
+	if(*longstr == '-')
+		l = htonl((uint32_t)strtol((char*)longstr, &end, 10));
+	else	l = htonl((uint32_t)strtoul((char*)longstr, &end, 10));
+
+	if(*end != 0) {
+		LDNS_FREE(r);
+		return LDNS_STATUS_ERR;
+     } else {
+		if (errno == ERANGE) {
+			LDNS_FREE(r);
+			return LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW;
+		}
+		memcpy(r, &l, sizeof(uint32_t));
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
+		LDNS_FREE(r);
+	        return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+	}
+}
+
+ldns_status
+ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
+{
+	char *end;
+	uint8_t *r = NULL;
+
+	r = LDNS_MALLOC(uint8_t);
+        if(!r) return LDNS_STATUS_MEM_ERR;
+
+	*r = (uint8_t)strtol((char*)bytestr, &end, 10);
+
+        if(*end != 0) {
+		LDNS_FREE(r);
+		return LDNS_STATUS_ERR;
+        } else {
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_INT8, sizeof(uint8_t), r);
+		LDNS_FREE(r);
+	        return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+        }
+}
+
+
+/*
+ * Checks whether the escaped value at **s is an decimal value or
+ * a 'normally' escaped character (and not eos)
+ *
+ * The string pointer at *s is increased by either 0 (on error), 1 (on
+ * normal escapes), or 3 (on decimals)
+ *
+ * Returns the number of bytes read from the escaped string, or
+ * 0 on error
+ */
+INLINE bool
+parse_escape(uint8_t *ch_p, const char** str_p)
+{
+	uint16_t val;
+
+	if ((*str_p)[0] && isdigit((*str_p)[0])  &&
+	    (*str_p)[1] && isdigit((*str_p)[1])  &&
+	    (*str_p)[2] && isdigit((*str_p)[2]))  {
+
+		val = (uint16_t)(((*str_p)[0] - '0') * 100 +
+				 ((*str_p)[1] - '0') *  10 +
+				 ((*str_p)[2] - '0'));
+
+		if (val > 255) {
+			goto error;
+		}
+		*ch_p = (uint8_t)val;
+		*str_p += 3;
+		return true;
+
+	} else if ((*str_p)[0] && !isdigit((*str_p)[0])) {
+
+		*ch_p = (uint8_t)*(*str_p)++;
+		return true;
+	}
+error:
+	*str_p = NULL;
+	return false; /* LDNS_STATUS_SYNTAX_BAD_ESCAPE */
+}
+
+INLINE bool
+parse_char(uint8_t *ch_p, const char** str_p)
+{
+	switch (**str_p) {
+
+	case '\0':	return false;
+
+	case '\\':	*str_p += 1;
+			return parse_escape(ch_p, str_p);
+
+	default:	*ch_p = (uint8_t)*(*str_p)++;
+			return true;
+	}
+}
+
+/*
+ * No special care is taken, all dots are translated into
+ * label seperators.
+ * Could be made more efficient....we do 3 memcpy's in total...
+ */
+ldns_status
+ldns_str2rdf_dname(ldns_rdf **d, const char *str)
+{
+	size_t len;
+
+	const char *s;
+	uint8_t *q, *pq, label_len;
+	uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
+	*d = NULL;
+
+	len = strlen((char*)str);
+	/* octet representation can make strings a lot longer than actual length */
+	if (len > LDNS_MAX_DOMAINLEN * 4) {
+		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+	}
+	if (0 == len) {
+		return LDNS_STATUS_DOMAINNAME_UNDERFLOW;
+	}
+
+	/* root label */
+	if (1 == len && *str == '.') {
+		*d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, "\0");
+		return LDNS_STATUS_OK;
+	}
+
+	/* get on with the rest */
+
+	/* s is on the current character in the string
+         * pq points to where the labellength is going to go
+         * label_len keeps track of the current label's length
+	 * q builds the dname inside the buf array
+	 */
+	len = 0;
+	q = buf+1;
+	pq = buf;
+	label_len = 0;
+	for (s = str; *s; s++, q++) {
+		if (q > buf + LDNS_MAX_DOMAINLEN) {
+			return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+		}
+		*q = 0;
+		switch (*s) {
+		case '.':
+			if (label_len > LDNS_MAX_LABELLEN) {
+				return LDNS_STATUS_LABEL_OVERFLOW;
+			}
+			if (label_len == 0) {
+				return LDNS_STATUS_EMPTY_LABEL;
+			}
+			len += label_len + 1;
+			*pq = label_len;
+			label_len = 0;
+			pq = q;
+			break;
+		case '\\':
+			/* octet value or literal char */
+			s += 1;
+			if (! parse_escape(q, &s)) {
+				return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
+			}
+			s -= 1;
+			label_len++;
+			break;
+		default:
+			*q = (uint8_t)*s;
+			label_len++;
+		}
+	}
+
+	/* add root label if last char was not '.' */
+	if (!ldns_dname_str_absolute(str)) {
+		if (q > buf + LDNS_MAX_DOMAINLEN) {
+			return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+		}
+                if (label_len > LDNS_MAX_LABELLEN) {
+                        return LDNS_STATUS_LABEL_OVERFLOW;
+                }
+                if (label_len == 0) { /* label_len 0 but not . at end? */
+                        return LDNS_STATUS_EMPTY_LABEL;
+                }
+		len += label_len + 1;
+		*pq = label_len;
+		*q = 0;
+	}
+	len++;
+
+	*d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, len, buf);
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_str2rdf_a(ldns_rdf **rd, const char *str)
+{
+	in_addr_t address;
+        if (inet_pton(AF_INET, (char*)str, &address) != 1) {
+                return LDNS_STATUS_INVALID_IP4;
+        } else {
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_A, sizeof(address), &address);
+        }
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
+{
+	uint8_t address[LDNS_IP6ADDRLEN + 1];
+
+	if (inet_pton(AF_INET6, (char*)str, address) != 1) {
+		return LDNS_STATUS_INVALID_IP6;
+	} else {
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
+	}
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_str(ldns_rdf **rd, const char *str)
+{
+	uint8_t *data, *dp, ch = 0;
+	size_t length;
+
+	/* Worst case space requirement. We'll realloc to actual size later. */
+	dp = data = LDNS_XMALLOC(uint8_t, strlen(str) > 255 ? 256 : (strlen(str) + 1));
+	if (! data) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	/* Fill data (up to 255 characters) */
+	while (parse_char(&ch, &str)) {
+		if (dp - data >= 255) {
+			LDNS_FREE(data);
+			return LDNS_STATUS_INVALID_STR;
+		}
+		*++dp = ch;
+	}
+	if (! str) {
+		return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
+	}
+	length = (size_t)(dp - data);
+	/* Fix last length byte */
+	data[0] = (uint8_t)length;
+
+	/* Lose the overmeasure */
+	data = LDNS_XREALLOC(dp = data, uint8_t, length + 1);
+	if (! data) {
+		LDNS_FREE(dp);
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	/* Create rdf */
+	*rd = ldns_rdf_new(LDNS_RDF_TYPE_STR, length + 1, data);
+	if (! *rd) {
+		LDNS_FREE(data);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
+{
+	const char *my_str = str;
+
+	char *my_ip_str;
+	size_t ip_str_len;
+
+	uint16_t family;
+	bool negation;
+	uint8_t afdlength = 0;
+	uint8_t *afdpart;
+	uint8_t prefix;
+
+	uint8_t *data;
+
+	size_t i = 0;
+
+	/* [!]afi:address/prefix */
+	if (strlen(my_str) < 2
+			|| strchr(my_str, ':') == NULL
+			|| strchr(my_str, '/') == NULL
+			|| strchr(my_str, ':') > strchr(my_str, '/')) {
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	if (my_str[0] == '!') {
+		negation = true;
+		my_str += 1;
+	} else {
+		negation = false;
+	}
+
+	family = (uint16_t) atoi(my_str);
+
+	my_str = strchr(my_str, ':') + 1;
+
+	/* need ip addr and only ip addr for inet_pton */
+	ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
+	my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
+        if(!my_ip_str) return LDNS_STATUS_MEM_ERR;
+	strncpy(my_ip_str, my_str, ip_str_len + 1);
+	my_ip_str[ip_str_len] = '\0';
+
+	if (family == 1) {
+		/* ipv4 */
+		afdpart = LDNS_XMALLOC(uint8_t, 4);
+                if(!afdpart) {
+                        LDNS_FREE(my_ip_str);
+                        return LDNS_STATUS_MEM_ERR;
+                }
+		if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
+                        LDNS_FREE(my_ip_str);
+                        LDNS_FREE(afdpart);
+			return LDNS_STATUS_INVALID_STR;
+		}
+		for (i = 0; i < 4; i++) {
+			if (afdpart[i] != 0) {
+				afdlength = i + 1;
+			}
+		}
+	} else if (family == 2) {
+		/* ipv6 */
+		afdpart = LDNS_XMALLOC(uint8_t, 16);
+                if(!afdpart) {
+                        LDNS_FREE(my_ip_str);
+                        return LDNS_STATUS_MEM_ERR;
+                }
+		if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
+                        LDNS_FREE(my_ip_str);
+                        LDNS_FREE(afdpart);
+			return LDNS_STATUS_INVALID_STR;
+		}
+		for (i = 0; i < 16; i++) {
+			if (afdpart[i] != 0) {
+				afdlength = i + 1;
+			}
+		}
+	} else {
+		/* unknown family */
+		LDNS_FREE(my_ip_str);
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	my_str = strchr(my_str, '/') + 1;
+	prefix = (uint8_t) atoi(my_str);
+
+	data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
+        if(!data) {
+		LDNS_FREE(afdpart);
+		LDNS_FREE(my_ip_str);
+		return LDNS_STATUS_INVALID_STR;
+        }
+	ldns_write_uint16(data, family);
+	data[2] = prefix;
+	data[3] = afdlength;
+	if (negation) {
+		/* set bit 1 of byte 3 */
+		data[3] = data[3] | 0x80;
+	}
+
+	memcpy(data + 4, afdpart, afdlength);
+
+	*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
+	LDNS_FREE(afdpart);
+	LDNS_FREE(data);
+	LDNS_FREE(my_ip_str);
+
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
+{
+	uint8_t *buffer;
+	int16_t i;
+
+	buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
+        if(!buffer) {
+                return LDNS_STATUS_MEM_ERR;
+        }
+
+	i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
+						   ldns_b64_ntop_calculate_size(strlen(str)));
+	if (-1 == i) {
+		LDNS_FREE(buffer);
+		return LDNS_STATUS_INVALID_B64;
+	} else {
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
+	}
+	LDNS_FREE(buffer);
+
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
+{
+	uint8_t *buffer;
+	int i;
+	/* first byte contains length of actual b32 data */
+	uint8_t len = ldns_b32_pton_calculate_size(strlen(str));
+	buffer = LDNS_XMALLOC(uint8_t, len + 1);
+        if(!buffer) {
+                return LDNS_STATUS_MEM_ERR;
+        }
+	buffer[0] = len;
+
+	i = ldns_b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
+							 ldns_b32_ntop_calculate_size(strlen(str)));
+	if (i < 0) {
+                LDNS_FREE(buffer);
+		return LDNS_STATUS_INVALID_B32_EXT;
+	} else {
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
+	}
+	LDNS_FREE(buffer);
+
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
+{
+	uint8_t *t, *t_orig;
+	int i;
+	size_t len;
+
+	len = strlen(str);
+
+	if (len > LDNS_MAX_RDFLEN * 2) {
+		return LDNS_STATUS_LABEL_OVERFLOW;
+	} else {
+		t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
+                if(!t) {
+                        return LDNS_STATUS_MEM_ERR;
+                }
+		t_orig = t;
+		/* Now process octet by octet... */
+		while (*str) {
+			*t = 0;
+			if (isspace((int) *str)) {
+				str++;
+			} else {
+				for (i = 16; i >= 1; i -= 15) {
+					while (*str && isspace((int) *str)) { str++; }
+					if (*str) {
+						if (isxdigit((int) *str)) {
+							*t += ldns_hexdigit_to_int(*str) * i;
+						} else {
+                                                        LDNS_FREE(t_orig);
+							return LDNS_STATUS_ERR;
+						}
+						++str;
+					}
+				}
+				++t;
+			}
+		}
+		*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
+		                            (size_t) (t - t_orig),
+		                            t_orig);
+		LDNS_FREE(t_orig);
+	}
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
+{
+	const char *delimiters = "\n\t ";
+	char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
+	ldns_buffer *str_buf;
+	ssize_t c;
+	uint16_t cur_type;
+	size_t type_count = 0;
+	ldns_rr_type type_list[65536];
+	if(!token) return LDNS_STATUS_MEM_ERR;
+	if(rd == NULL) {
+		LDNS_FREE(token);
+		return LDNS_STATUS_NULL;
+	}
+
+	str_buf = LDNS_MALLOC(ldns_buffer);
+	if(!str_buf) {
+		LDNS_FREE(token);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
+	if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
+		LDNS_FREE(str_buf);
+		LDNS_FREE(token);
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
+                if(type_count >= sizeof(type_list)) {
+		        LDNS_FREE(str_buf);
+		        LDNS_FREE(token);
+                        return LDNS_STATUS_ERR;
+                }
+		cur_type = ldns_get_rr_type_by_name(token);
+		type_list[type_count] = cur_type;
+		type_count++;
+	}
+
+	*rd = ldns_dnssec_create_nsec_bitmap(type_list,
+	                                     type_count,
+	                                     LDNS_RR_TYPE_NSEC);
+
+	LDNS_FREE(token);
+	ldns_buffer_free(str_buf);
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_type(ldns_rdf **rd, const char *str)
+{
+	uint16_t type;
+	type = htons(ldns_get_rr_type_by_name(str));
+	/* ldns_rr_type is a 16 bit value */
+	*rd = ldns_rdf_new_frm_data(
+		LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_class(ldns_rdf **rd, const char *str)
+{
+	uint16_t klass;
+	klass = htons(ldns_get_rr_class_by_name(str));
+	/* class is 16 bit */
+	*rd = ldns_rdf_new_frm_data(
+		LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+/* An certificate alg field can either be specified as a 8 bits number
+ * or by its symbolic name. Handle both
+ */
+ldns_status
+ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
+{
+	ldns_lookup_table *lt;
+	ldns_status st;
+	uint8_t idd[2];
+	lt = ldns_lookup_by_name(ldns_cert_algorithms, str);
+	st = LDNS_STATUS_OK;
+
+	if (lt) {
+		ldns_write_uint16(idd, (uint16_t) lt->id);
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
+		if (!*rd) {
+			st = LDNS_STATUS_ERR;
+		}
+	} else {
+		/* try as-is (a number) */
+		st = ldns_str2rdf_int16(rd, str);
+		if (st == LDNS_STATUS_OK &&
+		    ldns_rdf2native_int16(*rd) == 0) {
+			st = LDNS_STATUS_CERT_BAD_ALGORITHM;
+		}
+	}
+
+	return st;
+}
+
+static ldns_lookup_table ldns_tlsa_certificate_usages[] = {
+	{ LDNS_TLSA_USAGE_PKIX_TA		, "PKIX-TA"  },
+	{ LDNS_TLSA_USAGE_PKIX_EE		, "PKIX-EE"  },
+	{ LDNS_TLSA_USAGE_DANE_TA		, "DANE-TA"  },
+	{ LDNS_TLSA_USAGE_DANE_EE		, "DANE-EE"  },
+	{ LDNS_TLSA_USAGE_PRIVCERT		, "PrivCert" }
+};
+
+static ldns_lookup_table ldns_tlsa_selectors[] = {
+	{ LDNS_TLSA_SELECTOR_CERT		, "Cert" },
+	{ LDNS_TLSA_SELECTOR_SPKI		, "SPKI" },
+	{ LDNS_TLSA_SELECTOR_PRIVSEL		, "PrivSel" }
+};
+
+static ldns_lookup_table ldns_tlsa_matching_types[] = {
+	{ LDNS_TLSA_MATCHING_TYPE_FULL		, "Full"      },
+	{ LDNS_TLSA_MATCHING_TYPE_SHA2_256	, "SHA2-256"  },
+	{ LDNS_TLSA_MATCHING_TYPE_SHA2_512	, "SHA2-512"  },
+	{ LDNS_TLSA_MATCHING_TYPE_PRIVMATCH	, "PrivMatch" }
+};
+
+static ldns_status
+ldns_str2rdf_mnemonic4int8(ldns_lookup_table *lt,
+		ldns_rdf **rd, const char *str)
+{
+	if ((lt = ldns_lookup_by_name(lt, str))) {
+		/* it was given as a integer */
+		*rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
+		if (!*rd)
+			return LDNS_STATUS_ERR;
+		else
+			return LDNS_STATUS_OK;
+	}
+	return ldns_str2rdf_int8(rd, str);
+}
+
+/* An alg field can either be specified as a 8 bits number
+ * or by its symbolic name. Handle both
+ */
+ldns_status
+ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
+{
+	return ldns_str2rdf_mnemonic4int8(ldns_algorithms, rd, str);
+}
+
+ldns_status
+ldns_str2rdf_certificate_usage(ldns_rdf **rd, const char *str)
+{
+	return ldns_str2rdf_mnemonic4int8(
+			ldns_tlsa_certificate_usages, rd, str);
+}
+
+ldns_status
+ldns_str2rdf_selector(ldns_rdf **rd, const char *str)
+{
+	return ldns_str2rdf_mnemonic4int8(ldns_tlsa_selectors, rd, str);
+}
+
+ldns_status
+ldns_str2rdf_matching_type(ldns_rdf **rd, const char *str)
+{
+	return ldns_str2rdf_mnemonic4int8(ldns_tlsa_matching_types, rd, str);
+}
+
+ldns_status
+ldns_str2rdf_unknown( ATTR_UNUSED(ldns_rdf **rd)
+		    , ATTR_UNUSED(const char *str)
+		    )
+{
+	/* this should be caught in an earlier time (general str2host for
+	   rr's */
+	return LDNS_STATUS_NOT_IMPL;
+}
+
+ldns_status
+ldns_str2rdf_service( ATTR_UNUSED(ldns_rdf **rd)
+		    , ATTR_UNUSED(const char *str)
+		    )
+{
+	/* is this used? is this actually WKS? or SRV? */
+	return LDNS_STATUS_NOT_IMPL;
+}
+
+static int
+loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
+{
+	/* read <digits>[.<digits>][mM] */
+	/* into mantissa exponent format for LOC type */
+	uint32_t meters = 0, cm = 0, val;
+	while (isblank(*my_str)) {
+		my_str++;
+	}
+	meters = (uint32_t)strtol(my_str, &my_str, 10);
+	if (*my_str == '.') {
+		my_str++;
+		cm = (uint32_t)strtol(my_str, &my_str, 10);
+	}
+	if (meters >= 1) {
+		*e = 2;
+		val = meters;
+	} else	{
+		*e = 0;
+		val = cm;
+	}
+	while(val >= 10) {
+		(*e)++;
+		val /= 10;
+	}
+	*m = (uint8_t)val;
+
+	if (*e > 9)
+		return 0;
+	if (*my_str == 'm' || *my_str == 'M') {
+		my_str++;
+	}
+	*endstr = my_str;
+	return 1;
+}
+
+ldns_status
+ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
+{
+	uint32_t latitude = 0;
+	uint32_t longitude = 0;
+	uint32_t altitude = 0;
+
+	uint8_t *data;
+	uint32_t equator = (uint32_t) ldns_power(2, 31);
+
+	uint32_t h = 0;
+	uint32_t m = 0;
+	uint8_t size_b = 1, size_e = 2;
+	uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
+	uint8_t vert_pre_b = 1, vert_pre_e = 3;
+
+	double s = 0.0;
+	bool northerness;
+	bool easterness;
+
+	char *my_str = (char *) str;
+
+	/* only support version 0 */
+	if (isdigit((int) *my_str)) {
+		h = (uint32_t) strtol(my_str, &my_str, 10);
+	} else {
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	while (isblank((int) *my_str)) {
+		my_str++;
+	}
+
+	if (isdigit((int) *my_str)) {
+		m = (uint32_t) strtol(my_str, &my_str, 10);
+	} else if (*my_str == 'N' || *my_str == 'S') {
+		goto north;
+	} else {
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	while (isblank((int) *my_str)) {
+		my_str++;
+	}
+
+	if (isdigit((int) *my_str)) {
+		s = strtod(my_str, &my_str);
+	}
+north:
+	while (isblank((int) *my_str)) {
+		my_str++;
+	}
+
+	if (*my_str == 'N') {
+		northerness = true;
+	} else if (*my_str == 'S') {
+		northerness = false;
+	} else {
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	my_str++;
+
+	/* store number */
+	s = 1000.0 * s;
+	/* add a little to make floor in conversion a round */
+	s += 0.0005;
+	latitude = (uint32_t) s;
+	latitude += 1000 * 60 * m;
+	latitude += 1000 * 60 * 60 * h;
+	if (northerness) {
+		latitude = equator + latitude;
+	} else {
+		latitude = equator - latitude;
+	}
+	while (isblank(*my_str)) {
+		my_str++;
+	}
+
+	if (isdigit((int) *my_str)) {
+		h = (uint32_t) strtol(my_str, &my_str, 10);
+	} else {
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	while (isblank((int) *my_str)) {
+		my_str++;
+	}
+
+	if (isdigit((int) *my_str)) {
+		m = (uint32_t) strtol(my_str, &my_str, 10);
+	} else if (*my_str == 'E' || *my_str == 'W') {
+		goto east;
+	} else {
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	while (isblank(*my_str)) {
+		my_str++;
+	}
+
+	if (isdigit((int) *my_str)) {
+		s = strtod(my_str, &my_str);
+	}
+
+east:
+	while (isblank(*my_str)) {
+		my_str++;
+	}
+
+	if (*my_str == 'E') {
+		easterness = true;
+	} else if (*my_str == 'W') {
+		easterness = false;
+	} else {
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	my_str++;
+
+	/* store number */
+	s *= 1000.0;
+	/* add a little to make floor in conversion a round */
+	s += 0.0005;
+	longitude = (uint32_t) s;
+	longitude += 1000 * 60 * m;
+	longitude += 1000 * 60 * 60 * h;
+
+	if (easterness) {
+		longitude += equator;
+	} else {
+		longitude = equator - longitude;
+	}
+
+	altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
+		10000000.0 + 0.5);
+	if (*my_str == 'm' || *my_str == 'M') {
+		my_str++;
+	}
+
+	if (strlen(my_str) > 0) {
+		if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
+			return LDNS_STATUS_INVALID_STR;
+	}
+
+	if (strlen(my_str) > 0) {
+		if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
+			return LDNS_STATUS_INVALID_STR;
+	}
+
+	if (strlen(my_str) > 0) {
+		if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
+			return LDNS_STATUS_INVALID_STR;
+	}
+
+	data = LDNS_XMALLOC(uint8_t, 16);
+        if(!data) {
+                return LDNS_STATUS_MEM_ERR;
+        }
+	data[0] = 0;
+	data[1] = 0;
+	data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
+	data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
+	data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
+	ldns_write_uint32(data + 4, latitude);
+	ldns_write_uint32(data + 8, longitude);
+	ldns_write_uint32(data + 12, altitude);
+
+	*rd = ldns_rdf_new_frm_data(
+		LDNS_RDF_TYPE_LOC, 16, data);
+
+	LDNS_FREE(data);
+	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
+{
+	uint8_t *bitmap = NULL;
+	uint8_t *data;
+	int bm_len = 0;
+
+	struct protoent *proto = NULL;
+	struct servent *serv = NULL;
+	int serv_port;
+
+	ldns_buffer *str_buf;
+
+	char *proto_str = NULL;
+	char *token;
+	if(strlen(str) == 0)
+		token = LDNS_XMALLOC(char, 50);
+	else 	token = LDNS_XMALLOC(char, strlen(str)+2);
+	if(!token) return LDNS_STATUS_MEM_ERR;
+
+	str_buf = LDNS_MALLOC(ldns_buffer);
+	if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
+	ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
+	if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
+		LDNS_FREE(str_buf);
+		LDNS_FREE(token);
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
+		if (!proto_str) {
+			proto_str = strdup(token);
+			if (!proto_str) {
+				LDNS_FREE(bitmap);
+				LDNS_FREE(token);
+	                        ldns_buffer_free(str_buf);
+				return LDNS_STATUS_INVALID_STR;
+			}
+		} else {
+			serv = getservbyname(token, proto_str);
+			if (serv) {
+				serv_port = (int) ntohs((uint16_t) serv->s_port);
+			} else {
+				serv_port = atoi(token);
+			}
+			if (serv_port / 8 >= bm_len) {
+				uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
+                                if(!b2) {
+					LDNS_FREE(bitmap);
+				        LDNS_FREE(token);
+	                                ldns_buffer_free(str_buf);
+				        free(proto_str);
+				        return LDNS_STATUS_INVALID_STR;
+                                }
+				bitmap = b2;
+				/* set to zero to be sure */
+				for (; bm_len <= serv_port / 8; bm_len++) {
+					bitmap[bm_len] = 0;
+				}
+			}
+			ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
+		}
+	}
+
+	if (!proto_str || !bitmap) {
+		LDNS_FREE(bitmap);
+		LDNS_FREE(token);
+	        ldns_buffer_free(str_buf);
+	        free(proto_str);
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	data = LDNS_XMALLOC(uint8_t, bm_len + 1);
+        if(!data) {
+	        LDNS_FREE(token);
+	        ldns_buffer_free(str_buf);
+	        LDNS_FREE(bitmap);
+	        free(proto_str);
+	        return LDNS_STATUS_INVALID_STR;
+        }
+    if (proto_str)
+		proto = getprotobyname(proto_str);
+	if (proto) {
+		data[0] = (uint8_t) proto->p_proto;
+	} else if (proto_str) {
+		data[0] = (uint8_t) atoi(proto_str);
+	}
+	memcpy(data + 1, bitmap, (size_t) bm_len);
+
+	*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
+
+	LDNS_FREE(data);
+	LDNS_FREE(token);
+	ldns_buffer_free(str_buf);
+	LDNS_FREE(bitmap);
+	free(proto_str);
+#ifdef HAVE_ENDSERVENT
+	endservent();
+#endif
+#ifdef HAVE_ENDPROTOENT
+	endprotoent();
+#endif
+
+	if(!*rd) return LDNS_STATUS_MEM_ERR;
+
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
+{
+    size_t len, i;
+    char* nsap_str = (char*) str;
+
+	/* just a hex string with optional dots? */
+	if (str[0] != '0' || str[1] != 'x') {
+		return LDNS_STATUS_INVALID_STR;
+	} else {
+		len = strlen(str);
+		for (i=0; i < len; i++) {
+			if (nsap_str[i] == '.')
+				nsap_str[i] = ' ';
+        }
+		return ldns_str2rdf_hex(rd, str+2);
+	}
+}
+
+ldns_status
+ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
+{
+    size_t len, i;
+    char* atma_str = (char*) str;
+	ldns_status status;
+
+	/* just a hex string with optional dots? */
+	len = strlen(str);
+	for (i=0; i < len; i++) {
+		if (atma_str[i] == '.')
+			atma_str[i] = ' ';
+	}
+	status = ldns_str2rdf_hex(rd, str);
+    if (status != LDNS_STATUS_OK) {
+		; /* probably in e.164 format than */
+	}
+	return status;
+}
+
+ldns_status
+ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
+{
+	uint8_t precedence = 0;
+	uint8_t gateway_type = 0;
+	uint8_t algorithm = 0;
+	char* gateway = NULL;
+	char* publickey = NULL;
+	uint8_t *data;
+	ldns_buffer *str_buf;
+	char *token;
+	int token_count = 0;
+	int ipseckey_len = 0;
+	ldns_rdf* gateway_rdf = NULL;
+	ldns_rdf* publickey_rdf = NULL;
+	ldns_status status = LDNS_STATUS_OK;
+	
+	if(strlen(str) == 0)
+		token = LDNS_XMALLOC(char, 256);
+	else	token = LDNS_XMALLOC(char, strlen(str)+2);
+	if(!token) return LDNS_STATUS_MEM_ERR;
+
+	str_buf = LDNS_MALLOC(ldns_buffer);
+	if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
+	ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
+	if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
+		LDNS_FREE(str_buf);
+		LDNS_FREE(token);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
+		switch (token_count) {
+				case 0:
+					precedence = (uint8_t)atoi(token);
+					break;
+				case 1:
+					gateway_type = (uint8_t)atoi(token);
+					break;
+				case 2:
+					algorithm = (uint8_t)atoi(token);
+					break;
+				case 3:
+					gateway = strdup(token);
+					if (!gateway || (gateway_type == 0 &&
+							(token[0] != '.' || token[1] != '\0'))) {
+						LDNS_FREE(gateway);
+						LDNS_FREE(token);
+						ldns_buffer_free(str_buf);
+						return LDNS_STATUS_INVALID_STR;
+					}
+					break;
+				case 4:
+					publickey = strdup(token);
+					break;
+				default:
+					LDNS_FREE(token);
+					ldns_buffer_free(str_buf);
+					return LDNS_STATUS_INVALID_STR;
+					break;
+		}
+		token_count++;
+	}
+
+	if (!gateway || !publickey) {
+		if (gateway)
+			LDNS_FREE(gateway);
+		if (publickey)
+			LDNS_FREE(publickey);
+		LDNS_FREE(token);
+		ldns_buffer_free(str_buf);
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	if (gateway_type == 1) {
+		status = ldns_str2rdf_a(&gateway_rdf, gateway);
+	} else if (gateway_type == 2) {
+		status = ldns_str2rdf_aaaa(&gateway_rdf, gateway);
+	} else if (gateway_type == 3) {
+		status = ldns_str2rdf_dname(&gateway_rdf, gateway);
+	}
+
+	if (status != LDNS_STATUS_OK) {
+		if (gateway)
+			LDNS_FREE(gateway);
+		if (publickey)
+			LDNS_FREE(publickey);
+		LDNS_FREE(token);
+		ldns_buffer_free(str_buf);
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	status = ldns_str2rdf_b64(&publickey_rdf, publickey);
+
+	if (status != LDNS_STATUS_OK) {
+		if (gateway)
+			LDNS_FREE(gateway);
+		if (publickey)
+			LDNS_FREE(publickey);
+		LDNS_FREE(token);
+		ldns_buffer_free(str_buf);
+		if (gateway_rdf) ldns_rdf_free(gateway_rdf);
+		return LDNS_STATUS_INVALID_STR;
+	}
+
+	/* now copy all into one ipseckey rdf */
+	if (gateway_type)
+		ipseckey_len = 3 + (int)ldns_rdf_size(gateway_rdf) + (int)ldns_rdf_size(publickey_rdf);
+	else
+		ipseckey_len = 3 + (int)ldns_rdf_size(publickey_rdf);
+
+	data = LDNS_XMALLOC(uint8_t, ipseckey_len);
+	if(!data) {
+		if (gateway)
+			LDNS_FREE(gateway);
+		if (publickey)
+			LDNS_FREE(publickey);
+		LDNS_FREE(token);
+		ldns_buffer_free(str_buf);
+		if (gateway_rdf) ldns_rdf_free(gateway_rdf);
+		if (publickey_rdf) ldns_rdf_free(publickey_rdf);
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	data[0] = precedence;
+	data[1] = gateway_type;
+	data[2] = algorithm;
+
+	if (gateway_type) {
+		memcpy(data + 3,
+			ldns_rdf_data(gateway_rdf), ldns_rdf_size(gateway_rdf));
+		memcpy(data + 3 + ldns_rdf_size(gateway_rdf),
+			ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
+	} else {
+		memcpy(data + 3,
+			ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
+	}
+
+	*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY, (uint16_t) ipseckey_len, data);
+
+	if (gateway)
+		LDNS_FREE(gateway);
+	if (publickey)
+		LDNS_FREE(publickey);
+	LDNS_FREE(token);
+	ldns_buffer_free(str_buf);
+	ldns_rdf_free(gateway_rdf);
+	ldns_rdf_free(publickey_rdf);
+	LDNS_FREE(data);
+	if(!*rd) return LDNS_STATUS_MEM_ERR;
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_str2rdf_ilnp64(ldns_rdf **rd, const char *str)
+{
+	unsigned int a, b, c, d;
+	uint16_t shorts[4];
+	int l;
+
+	if (sscanf(str, "%4x:%4x:%4x:%4x%n", &a, &b, &c, &d, &l) != 4 ||
+			l != (int)strlen(str) || /* more data to read */
+			strpbrk(str, "+-")       /* signed hexes */
+			) {
+		return LDNS_STATUS_INVALID_ILNP64;
+	} else {
+		shorts[0] = htons(a);
+		shorts[1] = htons(b);
+		shorts[2] = htons(c);
+		shorts[3] = htons(d);
+		*rd = ldns_rdf_new_frm_data(
+			LDNS_RDF_TYPE_ILNP64, 4 * sizeof(uint16_t), &shorts);
+	}
+	return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_eui48(ldns_rdf **rd, const char *str)
+{
+	unsigned int a, b, c, d, e, f;
+	uint8_t bytes[6];
+	int l;
+
+	if (sscanf(str, "%2x-%2x-%2x-%2x-%2x-%2x%n",
+			&a, &b, &c, &d, &e, &f, &l) != 6 ||
+			l != (int)strlen(str)) {
+		return LDNS_STATUS_INVALID_EUI48;
+	} else {
+		bytes[0] = a;
+		bytes[1] = b;
+		bytes[2] = c;
+		bytes[3] = d;
+		bytes[4] = e;
+		bytes[5] = f;
+		*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_EUI48, 6, &bytes);
+	}
+	return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_eui64(ldns_rdf **rd, const char *str)
+{
+	unsigned int a, b, c, d, e, f, g, h;
+	uint8_t bytes[8];
+	int l;
+
+	if (sscanf(str, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n",
+			&a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 ||
+			l != (int)strlen(str)) {
+		return LDNS_STATUS_INVALID_EUI64;
+	} else {
+		bytes[0] = a;
+		bytes[1] = b;
+		bytes[2] = c;
+		bytes[3] = d;
+		bytes[4] = e;
+		bytes[5] = f;
+		bytes[6] = g;
+		bytes[7] = h;
+		*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_EUI64, 8, &bytes);
+	}
+	return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
+}
+
+ldns_status
+ldns_str2rdf_tag(ldns_rdf **rd, const char *str)
+{
+	uint8_t *data;
+	const char* ptr;
+
+	if (strlen(str) > 255) {
+		return LDNS_STATUS_INVALID_TAG;
+	}
+	for (ptr = str; *ptr; ptr++) {
+		if (! isalnum(*ptr)) {
+			return LDNS_STATUS_INVALID_TAG;
+		}
+	}
+	data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
+        if (!data) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	data[0] = strlen(str);
+	memcpy(data + 1, str, strlen(str));
+
+	*rd = ldns_rdf_new(LDNS_RDF_TYPE_TAG, strlen(str) + 1, data);
+	if (!*rd) {
+		LDNS_FREE(data);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_str2rdf_long_str(ldns_rdf **rd, const char *str)
+{
+	uint8_t *data, *dp, ch = 0;
+	size_t length;
+
+	/* Worst case space requirement. We'll realloc to actual size later. */
+	dp = data = LDNS_XMALLOC(uint8_t, strlen(str));
+        if (! data) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	/* Fill data with parsed bytes */
+	while (parse_char(&ch, &str)) {
+		*dp++ = ch;
+		if (dp - data > LDNS_MAX_RDFLEN) {
+			LDNS_FREE(data);
+			return LDNS_STATUS_INVALID_STR;
+		}
+	}
+	if (! str) {
+		return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
+	}
+	length = (size_t)(dp - data);
+
+	/* Lose the overmeasure */
+	data = LDNS_XREALLOC(dp = data, uint8_t, length);
+	if (! data) {
+		LDNS_FREE(dp);
+		return LDNS_STATUS_MEM_ERR;
+	}
+
+	/* Create rdf */
+	*rd = ldns_rdf_new(LDNS_RDF_TYPE_LONG_STR, length, data);
+	if (! *rd) {
+		LDNS_FREE(data);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_str2rdf_hip(ldns_rdf **rd, const char *str)
+{
+	const char *hit = strchr(str, ' ') + 1;
+	const char *pk  = hit == NULL ? NULL : strchr(hit, ' ') + 1;
+	size_t hit_size = hit == NULL ? 0
+	                : pk  == NULL ? strlen(hit) : (size_t) (pk - hit) - 1;
+	size_t  pk_size = pk  == NULL ? 0 : strlen(pk);
+	size_t hit_wire_size = (hit_size + 1) / 2;
+	size_t  pk_wire_size = ldns_b64_pton_calculate_size(pk_size);
+	size_t rdf_size = 4 + hit_wire_size + pk_wire_size;
+
+	char *endptr; /* utility var for strtol usage */
+	int algorithm = strtol(str, &endptr, 10);
+
+	uint8_t *data, *dp;
+	int hi, lo, written;
+
+	if (hit_size == 0 || pk_size == 0 || (hit_size + 1) / 2 > 255
+			|| rdf_size > LDNS_MAX_RDFLEN
+			|| algorithm < 0 || algorithm > 255
+			|| (errno != 0 && algorithm == 0) /* out of range */
+			|| endptr == str                  /* no digits    */) {
+
+		return LDNS_STATUS_SYNTAX_ERR;
+	}
+	if ((data = LDNS_XMALLOC(uint8_t, rdf_size)) == NULL) {
+
+		return LDNS_STATUS_MEM_ERR;
+	}
+	/* From RFC 5205 section 5. HIP RR Storage Format:
+	 *************************************************
+
+	0                   1                   2                   3
+	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|  HIT length   | PK algorithm  |          PK length            |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|                                                               |
+	~                           HIT                                 ~
+	|                                                               |
+	+                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|                     |                                         |
+	+-+-+-+-+-+-+-+-+-+-+-+                                         +
+	|                           Public Key                          |
+	~                                                               ~
+	|                                                               |
+	+                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|                               |                               |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
+	|                                                               |
+	~                       Rendezvous Servers                      ~
+	|                                                               |
+	+             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|             |
+	+-+-+-+-+-+-+-+                                                    */
+
+	data[0] = (uint8_t) hit_wire_size;
+	data[1] = (uint8_t) algorithm;
+
+	for (dp = data + 4; *hit && *hit != ' '; dp++) {
+
+		if ((hi = ldns_hexdigit_to_int(*hit++)) == -1 ||
+		    (lo = ldns_hexdigit_to_int(*hit++)) == -1) {
+
+			LDNS_FREE(data);
+			return LDNS_STATUS_INVALID_HEX;
+		}
+		*dp = (uint8_t) hi << 4 | lo;
+	}
+	if ((written = ldns_b64_pton(pk, dp, pk_wire_size)) <= 0) {
+
+		LDNS_FREE(data);
+		return LDNS_STATUS_INVALID_B64;
+	}
+
+	/* Because ldns_b64_pton_calculate_size isn't always correct:
+	 * (we have to fix it at some point)
+	 */
+	pk_wire_size = (uint16_t) written;
+	ldns_write_uint16(data + 2, pk_wire_size);
+	rdf_size = 4 + hit_wire_size + pk_wire_size;
+
+	/* Create rdf */
+	if (! (*rd = ldns_rdf_new(LDNS_RDF_TYPE_HIP, rdf_size, data))) {
+
+		LDNS_FREE(data);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
diff --git a/ldns/src/tsig.c b/ldns/src/tsig.c
new file mode 100644
index 0000000..53aa85e
--- /dev/null
+++ b/ldns/src/tsig.c
@@ -0,0 +1,470 @@
+/*
+ * tsig.c
+ *
+ * contains the functions needed for TSIG [RFC2845]
+ *
+ * (c) 2005-2006 NLnet Labs
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <strings.h>
+
+#ifdef HAVE_SSL
+#include <openssl/hmac.h>
+#include <openssl/md5.h>
+#endif /* HAVE_SSL */
+
+char *
+ldns_tsig_algorithm(ldns_tsig_credentials *tc)
+{
+	return tc->algorithm;
+}
+
+char *
+ldns_tsig_keyname(ldns_tsig_credentials *tc)
+{
+	return tc->keyname;
+}
+
+char *
+ldns_tsig_keydata(ldns_tsig_credentials *tc)
+{
+	return tc->keydata;
+}
+
+char *
+ldns_tsig_keyname_clone(ldns_tsig_credentials *tc)
+{
+	return strdup(tc->keyname);
+}
+
+char *
+ldns_tsig_keydata_clone(ldns_tsig_credentials *tc)
+{
+	return strdup(tc->keydata);
+}
+
+/*
+ *  Makes an exact copy of the wire, but with the tsig rr removed
+ */
+static uint8_t *
+ldns_tsig_prepare_pkt_wire(uint8_t *wire, size_t wire_len, size_t *result_len)
+{
+	uint8_t *wire2 = NULL;
+	uint16_t qd_count;
+	uint16_t an_count;
+	uint16_t ns_count;
+	uint16_t ar_count;
+	ldns_rr *rr;
+
+	size_t pos;
+	uint16_t i;
+
+	ldns_status status;
+
+	if(wire_len < LDNS_HEADER_SIZE) {
+		return NULL;
+	}
+	/* fake parse the wire */
+	qd_count = LDNS_QDCOUNT(wire);
+	an_count = LDNS_ANCOUNT(wire);
+	ns_count = LDNS_NSCOUNT(wire);
+	ar_count = LDNS_ARCOUNT(wire);
+
+	if (ar_count > 0) {
+		ar_count--;
+	} else {
+		return NULL;
+	}
+
+	pos = LDNS_HEADER_SIZE;
+
+	for (i = 0; i < qd_count; i++) {
+		status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_QUESTION);
+		if (status != LDNS_STATUS_OK) {
+			return NULL;
+		}
+		ldns_rr_free(rr);
+	}
+
+	for (i = 0; i < an_count; i++) {
+		status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_ANSWER);
+		if (status != LDNS_STATUS_OK) {
+			return NULL;
+		}
+		ldns_rr_free(rr);
+	}
+
+	for (i = 0; i < ns_count; i++) {
+		status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_AUTHORITY);
+		if (status != LDNS_STATUS_OK) {
+			return NULL;
+		}
+		ldns_rr_free(rr);
+	}
+
+	for (i = 0; i < ar_count; i++) {
+		status = ldns_wire2rr(&rr, wire, wire_len, &pos,
+				LDNS_SECTION_ADDITIONAL);
+		if (status != LDNS_STATUS_OK) {
+			return NULL;
+		}
+		ldns_rr_free(rr);
+	}
+
+	*result_len = pos;
+	wire2 = LDNS_XMALLOC(uint8_t, *result_len);
+	if(!wire2) {
+		return NULL;
+	}
+	memcpy(wire2, wire, *result_len);
+
+	ldns_write_uint16(wire2 + LDNS_ARCOUNT_OFF, ar_count);
+
+	return wire2;
+}
+
+#ifdef HAVE_SSL
+static const EVP_MD *
+ldns_digest_function(char *name)
+{
+	/* these are the mandatory algorithms from RFC4635 */
+	/* The optional algorithms are not yet implemented */
+	if (strcasecmp(name, "hmac-sha256.") == 0) {
+#ifdef HAVE_EVP_SHA256
+		return EVP_sha256();
+#else
+		return NULL;
+#endif
+	} else if (strcasecmp(name, "hmac-sha1.") == 0) {
+		return EVP_sha1();
+	} else if (strcasecmp(name, "hmac-md5.sig-alg.reg.int.") == 0) {
+		return EVP_md5();
+	} else {
+		return NULL;
+	}
+}
+#endif
+
+#ifdef HAVE_SSL
+static ldns_status
+ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
+		const char *key_data, ldns_rdf *key_name_rdf, ldns_rdf *fudge_rdf,
+		ldns_rdf *algorithm_rdf, ldns_rdf *time_signed_rdf, ldns_rdf *error_rdf,
+		ldns_rdf *other_data_rdf, ldns_rdf *orig_mac_rdf, int tsig_timers_only)
+{
+	ldns_status status;
+	char *wireformat;
+	int wiresize;
+	unsigned char *mac_bytes = NULL;
+	unsigned char *key_bytes = NULL;
+	int key_size;
+	const EVP_MD *digester;
+	char *algorithm_name = NULL;
+	unsigned int md_len = EVP_MAX_MD_SIZE;
+	ldns_rdf *result = NULL;
+	ldns_buffer *data_buffer = NULL;
+	ldns_rdf *canonical_key_name_rdf = NULL;
+	ldns_rdf *canonical_algorithm_rdf = NULL;
+	
+	if (key_name_rdf == NULL || algorithm_rdf == NULL) {
+		return LDNS_STATUS_NULL;
+	}
+	canonical_key_name_rdf  = ldns_rdf_clone(key_name_rdf);
+	if (canonical_key_name_rdf == NULL) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	canonical_algorithm_rdf = ldns_rdf_clone(algorithm_rdf);
+	if (canonical_algorithm_rdf == NULL) {
+		ldns_rdf_deep_free(canonical_key_name_rdf);
+		return LDNS_STATUS_MEM_ERR;
+	}
+	/*
+	 * prepare the digestable information
+	 */
+	data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
+	if (!data_buffer) {
+		status = LDNS_STATUS_MEM_ERR;
+		goto clean;
+	}
+	/* if orig_mac is not NULL, add it too */
+	if (orig_mac_rdf) {
+		(void) ldns_rdf2buffer_wire(data_buffer, orig_mac_rdf);
+ 	}
+	ldns_buffer_write(data_buffer, pkt_wire, pkt_wire_size);
+	if (!tsig_timers_only) {
+		ldns_dname2canonical(canonical_key_name_rdf);
+		(void)ldns_rdf2buffer_wire(data_buffer, 
+				canonical_key_name_rdf);
+		ldns_buffer_write_u16(data_buffer, LDNS_RR_CLASS_ANY);
+		ldns_buffer_write_u32(data_buffer, 0);
+		ldns_dname2canonical(canonical_algorithm_rdf);
+		(void)ldns_rdf2buffer_wire(data_buffer, 
+				canonical_algorithm_rdf);
+	}
+	(void)ldns_rdf2buffer_wire(data_buffer, time_signed_rdf);
+	(void)ldns_rdf2buffer_wire(data_buffer, fudge_rdf);
+	if (!tsig_timers_only) {
+		(void)ldns_rdf2buffer_wire(data_buffer, error_rdf);
+		(void)ldns_rdf2buffer_wire(data_buffer, other_data_rdf);
+	}
+
+	wireformat = (char *) data_buffer->_data;
+	wiresize = (int) ldns_buffer_position(data_buffer);
+
+	algorithm_name = ldns_rdf2str(algorithm_rdf);
+	if(!algorithm_name) {
+		status = LDNS_STATUS_MEM_ERR;
+		goto clean;
+	}
+
+	/* prepare the key */
+	key_bytes = LDNS_XMALLOC(unsigned char,
+			ldns_b64_pton_calculate_size(strlen(key_data)));
+	if(!key_bytes) {
+		status = LDNS_STATUS_MEM_ERR;
+		goto clean;
+	}
+	key_size = ldns_b64_pton(key_data, key_bytes,
+	ldns_b64_pton_calculate_size(strlen(key_data)));
+	if (key_size < 0) {
+		status = LDNS_STATUS_INVALID_B64;
+		goto clean;
+	}
+	/* hmac it */
+	/* 2 spare bytes for the length */
+	mac_bytes = LDNS_XMALLOC(unsigned char, md_len+2);
+	if(!mac_bytes) {
+		status = LDNS_STATUS_MEM_ERR;
+		goto clean;
+	}
+	memset(mac_bytes, 0, md_len+2);
+
+	digester = ldns_digest_function(algorithm_name);
+
+	if (digester) {
+		(void) HMAC(digester, key_bytes, key_size, (void *)wireformat,
+		            (size_t) wiresize, mac_bytes + 2, &md_len);
+
+		ldns_write_uint16(mac_bytes, md_len);
+		result = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16_DATA, md_len + 2,
+				mac_bytes);
+	} else {
+		status = LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
+		goto clean;
+	}
+	*tsig_mac = result;
+	status = LDNS_STATUS_OK;
+  clean:
+	LDNS_FREE(mac_bytes);
+	LDNS_FREE(key_bytes);
+	LDNS_FREE(algorithm_name);
+	ldns_buffer_free(data_buffer);
+	ldns_rdf_deep_free(canonical_algorithm_rdf);
+	ldns_rdf_deep_free(canonical_key_name_rdf);
+	return status;
+}
+#endif /*  HAVE_SSL */
+
+
+#ifdef HAVE_SSL
+bool
+ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char *key_name,
+	const char *key_data, ldns_rdf *orig_mac_rdf)
+{
+	return ldns_pkt_tsig_verify_next(pkt, wire, wirelen, key_name, key_data, orig_mac_rdf, 0);
+}
+
+bool
+ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char* key_name,
+	const char *key_data, ldns_rdf *orig_mac_rdf, int tsig_timers_only)
+{
+	ldns_rdf *fudge_rdf;
+	ldns_rdf *algorithm_rdf;
+	ldns_rdf *time_signed_rdf;
+	ldns_rdf *orig_id_rdf;
+	ldns_rdf *error_rdf;
+	ldns_rdf *other_data_rdf;
+	ldns_rdf *pkt_mac_rdf;
+	ldns_rdf *my_mac_rdf;
+	ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name);
+	uint16_t pkt_id, orig_pkt_id;
+	ldns_status status;
+
+	uint8_t *prepared_wire = NULL;
+	size_t prepared_wire_size = 0;
+
+	ldns_rr *orig_tsig = ldns_pkt_tsig(pkt);
+
+	if (!orig_tsig || ldns_rr_rd_count(orig_tsig) <= 6) {
+		ldns_rdf_deep_free(key_name_rdf);
+		return false;
+	}
+	algorithm_rdf = ldns_rr_rdf(orig_tsig, 0);
+	time_signed_rdf = ldns_rr_rdf(orig_tsig, 1);
+	fudge_rdf = ldns_rr_rdf(orig_tsig, 2);
+	pkt_mac_rdf = ldns_rr_rdf(orig_tsig, 3);
+	orig_id_rdf = ldns_rr_rdf(orig_tsig, 4);
+	error_rdf = ldns_rr_rdf(orig_tsig, 5);
+	other_data_rdf = ldns_rr_rdf(orig_tsig, 6);
+
+	/* remove temporarily */
+	ldns_pkt_set_tsig(pkt, NULL);
+	/* temporarily change the id to the original id */
+	pkt_id = ldns_pkt_id(pkt);
+	orig_pkt_id = ldns_rdf2native_int16(orig_id_rdf);
+	ldns_pkt_set_id(pkt, orig_pkt_id);
+
+	prepared_wire = ldns_tsig_prepare_pkt_wire(wire, wirelen, &prepared_wire_size);
+
+	status = ldns_tsig_mac_new(&my_mac_rdf, prepared_wire, prepared_wire_size,
+			key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
+			time_signed_rdf, error_rdf, other_data_rdf, orig_mac_rdf, tsig_timers_only);
+
+	LDNS_FREE(prepared_wire);
+
+	if (status != LDNS_STATUS_OK) {
+		ldns_rdf_deep_free(key_name_rdf);
+		return false;
+	}
+	/* Put back the values */
+	ldns_pkt_set_tsig(pkt, orig_tsig);
+	ldns_pkt_set_id(pkt, pkt_id);
+
+	ldns_rdf_deep_free(key_name_rdf);
+
+	if (ldns_rdf_compare(pkt_mac_rdf, my_mac_rdf) == 0) {
+		ldns_rdf_deep_free(my_mac_rdf);
+		return true;
+	} else {
+		ldns_rdf_deep_free(my_mac_rdf);
+		return false;
+	}
+}
+#endif /* HAVE_SSL */
+
+#ifdef HAVE_SSL
+ldns_status
+ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data,
+	uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac)
+{
+	return ldns_pkt_tsig_sign_next(pkt, key_name, key_data, fudge, algorithm_name, query_mac, 0);
+}
+
+ldns_status
+ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data,
+	uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only)
+{
+	ldns_rr *tsig_rr;
+	ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name);
+	ldns_rdf *fudge_rdf = NULL;
+	ldns_rdf *orig_id_rdf = NULL;
+	ldns_rdf *algorithm_rdf;
+	ldns_rdf *error_rdf = NULL;
+	ldns_rdf *mac_rdf = NULL;
+	ldns_rdf *other_data_rdf = NULL;
+
+	ldns_status status = LDNS_STATUS_OK;
+
+	uint8_t *pkt_wire = NULL;
+	size_t pkt_wire_len;
+
+	struct timeval tv_time_signed;
+	uint8_t *time_signed = NULL;
+	ldns_rdf *time_signed_rdf = NULL;
+
+	algorithm_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, algorithm_name);
+	if(!key_name_rdf || !algorithm_rdf) {
+		status = LDNS_STATUS_MEM_ERR;
+		goto clean;
+	}
+
+	/* eww don't have create tsigtime rdf yet :( */
+	/* bleh :p */
+	if (gettimeofday(&tv_time_signed, NULL) == 0) {
+		time_signed = LDNS_XMALLOC(uint8_t, 6);
+		if(!time_signed) {
+			status = LDNS_STATUS_MEM_ERR;
+			goto clean;
+		}
+		ldns_write_uint64_as_uint48(time_signed,
+				(uint64_t)tv_time_signed.tv_sec);
+	} else {
+		status = LDNS_STATUS_INTERNAL_ERR;
+		goto clean;
+	}
+
+	time_signed_rdf = ldns_rdf_new(LDNS_RDF_TYPE_TSIGTIME, 6, time_signed);
+	if(!time_signed_rdf) {
+		LDNS_FREE(time_signed);
+		status = LDNS_STATUS_MEM_ERR;
+		goto clean;
+	}
+
+	fudge_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, fudge);
+
+	orig_id_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, ldns_pkt_id(pkt));
+
+	error_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 0);
+
+	other_data_rdf = ldns_native2rdf_int16_data(0, NULL);
+
+	if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) {
+		status = LDNS_STATUS_MEM_ERR;
+		goto clean;
+	}
+
+	if (ldns_pkt2wire(&pkt_wire, pkt, &pkt_wire_len) != LDNS_STATUS_OK) {
+		status = LDNS_STATUS_ERR;
+		goto clean;
+	}
+
+	status = ldns_tsig_mac_new(&mac_rdf, pkt_wire, pkt_wire_len,
+			key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
+			time_signed_rdf, error_rdf, other_data_rdf, query_mac, tsig_timers_only);
+
+	if (!mac_rdf) {
+		goto clean;
+	}
+
+	LDNS_FREE(pkt_wire);
+
+	/* Create the TSIG RR */
+	tsig_rr = ldns_rr_new();
+	if(!tsig_rr) {
+		status = LDNS_STATUS_MEM_ERR;
+		goto clean;
+	}
+	ldns_rr_set_owner(tsig_rr, key_name_rdf);
+	ldns_rr_set_class(tsig_rr, LDNS_RR_CLASS_ANY);
+	ldns_rr_set_type(tsig_rr, LDNS_RR_TYPE_TSIG);
+	ldns_rr_set_ttl(tsig_rr, 0);
+
+	ldns_rr_push_rdf(tsig_rr, algorithm_rdf);
+	ldns_rr_push_rdf(tsig_rr, time_signed_rdf);
+	ldns_rr_push_rdf(tsig_rr, fudge_rdf);
+	ldns_rr_push_rdf(tsig_rr, mac_rdf);
+	ldns_rr_push_rdf(tsig_rr, orig_id_rdf);
+	ldns_rr_push_rdf(tsig_rr, error_rdf);
+	ldns_rr_push_rdf(tsig_rr, other_data_rdf);
+
+	ldns_pkt_set_tsig(pkt, tsig_rr);
+
+	return status;
+
+  clean:
+	LDNS_FREE(pkt_wire);
+	ldns_rdf_free(key_name_rdf);
+	ldns_rdf_free(algorithm_rdf);
+	ldns_rdf_free(time_signed_rdf);
+	ldns_rdf_free(fudge_rdf);
+	ldns_rdf_free(orig_id_rdf);
+	ldns_rdf_free(error_rdf);
+	ldns_rdf_free(other_data_rdf);
+	return status;
+}
+#endif /* HAVE_SSL */
diff --git a/ldns/src/update.c b/ldns/src/update.c
new file mode 100644
index 0000000..74e9d19
--- /dev/null
+++ b/ldns/src/update.c
@@ -0,0 +1,325 @@
+/* update.c
+ *
+ * Functions for RFC 2136 Dynamic Update
+ *
+ * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <strings.h>
+#include <stdlib.h>
+#include <limits.h>
+
+/*
+ * RFC 2136 sections mapped to RFC 1035:
+ *              zone/ZO -- QD/question
+ *     prerequisites/PR -- AN/answers
+ *           updates/UP -- NS/authority records
+ *   additional data/AD -- AR/additional records
+ */
+
+ldns_pkt *
+ldns_update_pkt_new(ldns_rdf *zone_rdf, ldns_rr_class c,
+    ldns_rr_list *pr_rrlist, ldns_rr_list *up_rrlist, ldns_rr_list *ad_rrlist)
+{
+	ldns_pkt *p;
+
+	if (!zone_rdf || !up_rrlist) {
+		return NULL;
+	}
+
+	if (c == 0) { 
+		c = LDNS_RR_CLASS_IN;
+	}
+
+	/* Create packet, fill in Zone Section. */
+	p = ldns_pkt_query_new(zone_rdf, LDNS_RR_TYPE_SOA, c, LDNS_RD);
+	if (!p) {
+		return NULL;
+	}
+	zone_rdf = NULL; /* No longer safe to use. */
+
+	ldns_pkt_set_opcode(p, LDNS_PACKET_UPDATE);
+
+	ldns_rr_list_deep_free(p->_authority);
+
+	ldns_pkt_set_authority(p, ldns_rr_list_clone(up_rrlist));
+
+	ldns_update_set_upcount(p, ldns_rr_list_rr_count(up_rrlist));
+
+	if (pr_rrlist) {
+		ldns_rr_list_deep_free(p->_answer); /*XXX access function */
+		ldns_pkt_set_answer(p, ldns_rr_list_clone(pr_rrlist));
+		ldns_update_set_prcount(p, ldns_rr_list_rr_count(pr_rrlist));
+	}
+
+	if (ad_rrlist) {
+		ldns_rr_list_deep_free(p->_additional);
+		ldns_pkt_set_additional(p, ldns_rr_list_clone(ad_rrlist));
+		ldns_update_set_adcount(p, ldns_rr_list_rr_count(ad_rrlist));
+	}
+	return p;
+}
+
+ldns_status
+ldns_update_pkt_tsig_add(ldns_pkt *p, ldns_resolver *r)
+{
+#ifdef HAVE_SSL
+	uint16_t fudge = 300; /* Recommended fudge. [RFC2845 6.4]  */
+	if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r))
+		return ldns_pkt_tsig_sign(p, ldns_resolver_tsig_keyname(r),
+		    ldns_resolver_tsig_keydata(r), fudge,
+		    ldns_resolver_tsig_algorithm(r), NULL);
+#else
+	/* do nothing */
+	(void)p;
+	(void)r;
+#endif /* HAVE_SSL */
+	/* No TSIG to do. */
+	return LDNS_STATUS_OK;
+}
+
+/* Move to higher.c or similar? */
+/* XXX doc */
+ldns_status
+ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r,
+    ldns_rr_class c, ldns_rdf **mname)
+{
+	ldns_rr		*soa_rr;
+	ldns_pkt	*query, *resp;
+
+	/* Nondestructive, so clone 'zone' here */
+	query = ldns_pkt_query_new(ldns_rdf_clone(zone), LDNS_RR_TYPE_SOA,
+	    c, LDNS_RD);
+	if (!query) {
+		return LDNS_STATUS_ERR;
+	}
+
+	ldns_pkt_set_random_id(query);
+	if (ldns_resolver_send_pkt(&resp, r, query) != LDNS_STATUS_OK) {
+		ldns_pkt_free(query);
+		return LDNS_STATUS_ERR;
+	}
+	ldns_pkt_free(query);
+	if (!resp) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* Expect a SOA answer. */
+	*mname = NULL;
+	while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_answer(resp)))) {
+		if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+				|| ldns_rr_rdf(soa_rr, 0) == NULL)
+			continue;
+		/* [RFC1035 3.3.13] */
+		*mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
+		break;
+	}
+	ldns_pkt_free(resp);
+
+	return *mname ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
+}
+
+/* Try to get zone and MNAME from SOA queries. */
+ldns_status
+ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r,
+    ldns_rr_class c, ldns_rdf **zone_rdf, ldns_rdf **mname_rdf)
+{
+	ldns_rr		*soa_rr, *rr;
+	ldns_rdf	*soa_zone = NULL, *soa_mname = NULL;
+	ldns_rdf	*ipaddr, *fqdn_rdf, *tmp;
+	ldns_rdf	**nslist;
+	ldns_pkt	*query, *resp;
+	ldns_resolver   *tmp_r;
+	size_t		i;
+
+	/* 
+	 * XXX Ok, this cannot be the best way to find this...?
+	 * XXX (I run into weird cache-related stuff here)
+	 */
+
+	/* Step 1 - first find a nameserver that should know *something* */
+	fqdn_rdf = ldns_dname_new_frm_str(fqdn);
+	query = ldns_pkt_query_new(fqdn_rdf, LDNS_RR_TYPE_SOA, c, LDNS_RD);
+	if (!query) {
+		return LDNS_STATUS_ERR;
+	}
+	fqdn_rdf = NULL;
+
+	ldns_pkt_set_random_id(query);
+	if (ldns_resolver_send_pkt(&resp, r, query) != LDNS_STATUS_OK) {
+		ldns_pkt_free(query);
+		return LDNS_STATUS_ERR;
+	}
+	ldns_pkt_free(query);
+	if (!resp) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* XXX Is it safe to only look in authority section here? */
+	while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
+		if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+				|| ldns_rr_rdf(soa_rr, 0) == NULL)
+			continue;
+		/* [RFC1035 3.3.13] */
+		soa_mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
+		break;
+	}
+	ldns_pkt_free(resp);
+	if (!soa_rr) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* Step 2 - find SOA MNAME IP address, add to resolver */
+	query = ldns_pkt_query_new(soa_mname, LDNS_RR_TYPE_A, c, LDNS_RD);
+	if (!query) {
+		return LDNS_STATUS_ERR;
+	}
+	soa_mname = NULL;
+
+	ldns_pkt_set_random_id(query);
+	if (ldns_resolver_send_pkt(&resp, r, query) != LDNS_STATUS_OK) {
+		ldns_pkt_free(query);
+		return LDNS_STATUS_ERR;
+	}
+	ldns_pkt_free(query);
+	if (!resp) {
+		return LDNS_STATUS_ERR;
+	}
+
+	if (ldns_pkt_ancount(resp) == 0) {
+		ldns_pkt_free(resp);
+		return LDNS_STATUS_ERR;
+	}
+
+	/* XXX There may be more than one answer RR here. */
+	rr = ldns_rr_list_pop_rr(ldns_pkt_answer(resp));
+	ipaddr = ldns_rr_rdf(rr, 0);
+
+	/* Put the SOA mname IP first in the nameserver list. */
+	if (!(tmp_r = ldns_resolver_clone(r))) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	nslist = ldns_resolver_nameservers(tmp_r);
+	for (i = 0; i < ldns_resolver_nameserver_count(tmp_r); i++) {
+		if (ldns_rdf_compare(ipaddr, nslist[i]) == 0) {
+			if (i) {
+				tmp = nslist[0];
+				nslist[0] = nslist[i];
+				nslist[i] = tmp;
+			}
+			break;
+		}
+	}
+	if (i >= ldns_resolver_nameserver_count(tmp_r)) {
+		/* SOA mname was not part of the resolver so add it first. */
+		(void) ldns_resolver_push_nameserver(tmp_r, ipaddr);
+		nslist = ldns_resolver_nameservers(tmp_r);
+		i = ldns_resolver_nameserver_count(tmp_r) - 1;
+		tmp = nslist[0];
+		nslist[0] = nslist[i];
+		nslist[i] = tmp;
+	}
+	ldns_pkt_free(resp);
+
+	/* Make sure to ask the first in the list, i.e SOA mname */
+	ldns_resolver_set_random(tmp_r, false);
+
+	/* Step 3 - Redo SOA query, sending to SOA MNAME directly. */
+	fqdn_rdf = ldns_dname_new_frm_str(fqdn);
+	query = ldns_pkt_query_new(fqdn_rdf, LDNS_RR_TYPE_SOA, c, LDNS_RD);
+	if (!query) {
+		ldns_resolver_free(tmp_r);
+		return LDNS_STATUS_ERR;
+	}
+	fqdn_rdf = NULL;
+
+	ldns_pkt_set_random_id(query);
+	if (ldns_resolver_send_pkt(&resp, tmp_r, query) != LDNS_STATUS_OK) {
+		ldns_pkt_free(query);
+		ldns_resolver_free(tmp_r);
+		return LDNS_STATUS_ERR;
+	}
+	ldns_resolver_free(tmp_r);
+	ldns_pkt_free(query);
+	if (!resp) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* XXX Is it safe to only look in authority section here, too? */
+	while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
+		if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
+				|| ldns_rr_rdf(soa_rr, 0) == NULL)
+			continue;
+		/* [RFC1035 3.3.13] */
+		soa_mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
+		soa_zone = ldns_rdf_clone(ldns_rr_owner(soa_rr));
+		break;
+	}
+	ldns_pkt_free(resp);
+	if (!soa_rr) {
+		return LDNS_STATUS_ERR;
+	}
+
+	/* That seems to have worked, pass results to caller. */
+	*zone_rdf = soa_zone;
+	*mname_rdf = soa_mname;
+	return LDNS_STATUS_OK;
+}	
+
+/*
+ * ldns_update_{get,set}_{zo,pr,up,ad}count
+ */
+
+uint16_t
+ldns_update_zocount(const ldns_pkt *p)
+{
+	return ldns_pkt_qdcount(p);
+}
+
+uint16_t
+ldns_update_prcount(const ldns_pkt *p)
+{
+	return ldns_pkt_ancount(p);
+}
+
+uint16_t
+ldns_update_upcount(const ldns_pkt *p)
+{
+	return ldns_pkt_nscount(p);
+}
+
+uint16_t
+ldns_update_ad(const ldns_pkt *p)
+{
+	return ldns_pkt_arcount(p);
+}
+
+void
+ldns_update_set_zo(ldns_pkt *p, uint16_t v)
+{
+	ldns_pkt_set_qdcount(p, v);
+}
+
+void
+ldns_update_set_prcount(ldns_pkt *p, uint16_t v)
+{
+	ldns_pkt_set_ancount(p, v);
+}
+
+void
+ldns_update_set_upcount(ldns_pkt *p, uint16_t v)
+{
+	ldns_pkt_set_nscount(p, v);
+}
+
+void
+ldns_update_set_adcount(ldns_pkt *p, uint16_t v)
+{
+	ldns_pkt_set_arcount(p, v);
+}
diff --git a/ldns/src/util.c b/ldns/src/util.c
new file mode 100644
index 0000000..33060d9
--- /dev/null
+++ b/ldns/src/util.c
@@ -0,0 +1,773 @@
+/*
+ * util.c
+ *
+ * some general memory functions
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+#include <ldns/config.h>
+
+#include <ldns/rdata.h>
+#include <ldns/rr.h>
+#include <ldns/util.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <ctype.h>
+
+#ifdef HAVE_SSL
+#include <openssl/rand.h>
+#endif
+
+ldns_lookup_table *
+ldns_lookup_by_name(ldns_lookup_table *table, const char *name)
+{
+	while (table->name != NULL) {
+		if (strcasecmp(name, table->name) == 0)
+			return table;
+		table++;
+	}
+	return NULL;
+}
+
+ldns_lookup_table *
+ldns_lookup_by_id(ldns_lookup_table *table, int id)
+{
+	while (table->name != NULL) {
+		if (table->id == id)
+			return table;
+		table++;
+	}
+	return NULL;
+}
+
+int
+ldns_get_bit(uint8_t bits[], size_t index)
+{
+	/*
+	 * The bits are counted from left to right, so bit #0 is the
+	 * left most bit.
+	 */
+	return (int) (bits[index / 8] & (1 << (7 - index % 8)));
+}
+
+int
+ldns_get_bit_r(uint8_t bits[], size_t index)
+{
+	/*
+	 * The bits are counted from right to left, so bit #0 is the
+	 * right most bit.
+	 */
+	return (int) bits[index / 8] & (1 << (index % 8));
+}
+
+void
+ldns_set_bit(uint8_t *byte, int bit_nr, bool value)
+{
+	/*
+	 * The bits are counted from right to left, so bit #0 is the
+	 * right most bit.
+	 */
+	if (bit_nr >= 0 && bit_nr < 8) {
+		if (value) {
+			*byte = *byte | (0x01 << bit_nr);
+		} else {
+			*byte = *byte & ~(0x01 << bit_nr);
+		}
+	}
+}
+
+int
+ldns_hexdigit_to_int(char ch)
+{
+	switch (ch) {
+	case '0': return 0;
+	case '1': return 1;
+	case '2': return 2;
+	case '3': return 3;
+	case '4': return 4;
+	case '5': return 5;
+	case '6': return 6;
+	case '7': return 7;
+	case '8': return 8;
+	case '9': return 9;
+	case 'a': case 'A': return 10;
+	case 'b': case 'B': return 11;
+	case 'c': case 'C': return 12;
+	case 'd': case 'D': return 13;
+	case 'e': case 'E': return 14;
+	case 'f': case 'F': return 15;
+	default:
+		return -1;
+	}
+}
+
+char
+ldns_int_to_hexdigit(int i)
+{
+	switch (i) {
+	case 0: return '0';
+	case 1: return '1';
+	case 2: return '2';
+	case 3: return '3';
+	case 4: return '4';
+	case 5: return '5';
+	case 6: return '6';
+	case 7: return '7';
+	case 8: return '8';
+	case 9: return '9';
+	case 10: return 'a';
+	case 11: return 'b';
+	case 12: return 'c';
+	case 13: return 'd';
+	case 14: return 'e';
+	case 15: return 'f';
+	default:
+		abort();
+	}
+}
+
+int
+ldns_hexstring_to_data(uint8_t *data, const char *str)
+{
+	size_t i;
+
+	if (!str || !data) {
+		return -1;
+	}
+
+	if (strlen(str) % 2 != 0) {
+		return -2;
+	}
+
+	for (i = 0; i < strlen(str) / 2; i++) {
+		data[i] =
+			16 * (uint8_t) ldns_hexdigit_to_int(str[i*2]) +
+			(uint8_t) ldns_hexdigit_to_int(str[i*2 + 1]);
+	}
+
+	return (int) i;
+}
+
+const char *
+ldns_version(void)
+{
+	return (char*)LDNS_VERSION;
+}
+
+/* Number of days per month (except for February in leap years). */
+static const int mdays[] = {
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+#define LDNS_MOD(x,y) (((x) % (y) < 0) ? ((x) % (y) + (y)) : ((x) % (y)))
+#define LDNS_DIV(x,y) (((x) % (y) < 0) ? ((x) / (y) -  1 ) : ((x) / (y)))
+
+static int
+is_leap_year(int year)
+{
+	return LDNS_MOD(year,   4) == 0 && (LDNS_MOD(year, 100) != 0 
+	    || LDNS_MOD(year, 400) == 0);
+}
+
+static int
+leap_days(int y1, int y2)
+{
+	--y1;
+	--y2;
+	return (LDNS_DIV(y2,   4) - LDNS_DIV(y1,   4)) - 
+	       (LDNS_DIV(y2, 100) - LDNS_DIV(y1, 100)) +
+	       (LDNS_DIV(y2, 400) - LDNS_DIV(y1, 400));
+}
+
+/*
+ * Code adapted from Python 2.4.1 sources (Lib/calendar.py).
+ */
+time_t
+ldns_mktime_from_utc(const struct tm *tm)
+{
+	int year = 1900 + tm->tm_year;
+	time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year);
+	time_t hours;
+	time_t minutes;
+	time_t seconds;
+	int i;
+
+	for (i = 0; i < tm->tm_mon; ++i) {
+		days += mdays[i];
+	}
+	if (tm->tm_mon > 1 && is_leap_year(year)) {
+		++days;
+	}
+	days += tm->tm_mday - 1;
+
+	hours = days * 24 + tm->tm_hour;
+	minutes = hours * 60 + tm->tm_min;
+	seconds = minutes * 60 + tm->tm_sec;
+
+	return seconds;
+}
+
+time_t
+mktime_from_utc(const struct tm *tm)
+{
+	return ldns_mktime_from_utc(tm);
+}
+
+#if SIZEOF_TIME_T <= 4
+
+static void
+ldns_year_and_yday_from_days_since_epoch(int64_t days, struct tm *result)
+{
+	int year = 1970;
+	int new_year;
+
+	while (days < 0 || days >= (int64_t) (is_leap_year(year) ? 366 : 365)) {
+		new_year = year + (int) LDNS_DIV(days, 365);
+		days -= (new_year - year) * 365;
+		days -= leap_days(year, new_year);
+		year  = new_year;
+	}
+	result->tm_year = year;
+	result->tm_yday = (int) days;
+}
+
+/* Number of days per month in a leap year. */
+static const int leap_year_mdays[] = {
+	31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+static void
+ldns_mon_and_mday_from_year_and_yday(struct tm *result)
+{
+	int idays = result->tm_yday;
+	const int *mon_lengths = is_leap_year(result->tm_year) ? 
+					leap_year_mdays : mdays;
+
+	result->tm_mon = 0;
+	while  (idays >= mon_lengths[result->tm_mon]) {
+		idays -= mon_lengths[result->tm_mon++];
+	}
+	result->tm_mday = idays + 1;
+}
+
+static void
+ldns_wday_from_year_and_yday(struct tm *result)
+{
+	result->tm_wday = 4 /* 1-1-1970 was a thursday */
+			+ LDNS_MOD((result->tm_year - 1970), 7) * LDNS_MOD(365, 7)
+			+ leap_days(1970, result->tm_year)
+			+ result->tm_yday;
+	result->tm_wday = LDNS_MOD(result->tm_wday, 7);
+	if (result->tm_wday < 0) {
+		result->tm_wday += 7;
+	}
+}
+
+static struct tm *
+ldns_gmtime64_r(int64_t clock, struct tm *result)
+{
+	result->tm_isdst = 0;
+	result->tm_sec   = (int) LDNS_MOD(clock, 60);
+	clock            =       LDNS_DIV(clock, 60);
+	result->tm_min   = (int) LDNS_MOD(clock, 60);
+	clock            =       LDNS_DIV(clock, 60);
+	result->tm_hour  = (int) LDNS_MOD(clock, 24);
+	clock            =       LDNS_DIV(clock, 24);
+
+	ldns_year_and_yday_from_days_since_epoch(clock, result);
+	ldns_mon_and_mday_from_year_and_yday(result);
+	ldns_wday_from_year_and_yday(result);
+	result->tm_year -= 1900;
+
+	return result;
+}
+
+#endif /* SIZEOF_TIME_T <= 4 */
+
+static int64_t
+ldns_serial_arithmitics_time(int32_t time, time_t now)
+{
+	int32_t offset = time - (int32_t) now;
+	return (int64_t) now + offset;
+}
+
+
+struct tm *
+ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result)
+{
+#if SIZEOF_TIME_T <= 4
+	int64_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
+	return  ldns_gmtime64_r(secs_since_epoch, result);
+#else
+	time_t  secs_since_epoch = ldns_serial_arithmitics_time(time, now);
+	return  gmtime_r(&secs_since_epoch, result);
+#endif
+}
+
+/**
+ * Init the random source
+ * applications should call this if they need entropy data within ldns
+ * If openSSL is available, it is automatically seeded from /dev/urandom
+ * or /dev/random
+ *
+ * If you need more entropy, or have no openssl available, this function
+ * MUST be called at the start of the program
+ *
+ * If openssl *is* available, this function just adds more entropy
+ **/
+int
+ldns_init_random(FILE *fd, unsigned int size)
+{
+	/* if fp is given, seed srandom with data from file
+	   otherwise use /dev/urandom */
+	FILE *rand_f;
+	uint8_t *seed;
+	size_t read = 0;
+	unsigned int seed_i;
+	struct timeval tv;
+
+	/* we'll need at least sizeof(unsigned int) bytes for the
+	   standard prng seed */
+	if (size < (unsigned int) sizeof(seed_i)){
+		size = (unsigned int) sizeof(seed_i);
+	}
+
+	seed = LDNS_XMALLOC(uint8_t, size);
+        if(!seed) {
+		return 1;
+        }
+
+	if (!fd) {
+		if ((rand_f = fopen("/dev/urandom", "r")) == NULL) {
+			/* no readable /dev/urandom, try /dev/random */
+			if ((rand_f = fopen("/dev/random", "r")) == NULL) {
+				/* no readable /dev/random either, and no entropy
+				   source given. we'll have to improvise */
+				for (read = 0; read < size; read++) {
+					gettimeofday(&tv, NULL);
+					seed[read] = (uint8_t) (tv.tv_usec % 256);
+				}
+			} else {
+				read = fread(seed, 1, size, rand_f);
+			}
+		} else {
+			read = fread(seed, 1, size, rand_f);
+		}
+	} else {
+		rand_f = fd;
+		read = fread(seed, 1, size, rand_f);
+	}
+
+	if (read < size) {
+		LDNS_FREE(seed);
+		if (!fd) fclose(rand_f);
+		return 1;
+	} else {
+#ifdef HAVE_SSL
+		/* Seed the OpenSSL prng (most systems have it seeded
+		   automatically, in that case this call just adds entropy */
+		RAND_seed(seed, (int) size);
+#else
+		/* Seed the standard prng, only uses the first
+		 * unsigned sizeof(unsiged int) bytes found in the entropy pool
+		 */
+		memcpy(&seed_i, seed, sizeof(seed_i));
+		srandom(seed_i);
+#endif
+		LDNS_FREE(seed);
+	}
+
+	if (!fd) {
+                if (rand_f) fclose(rand_f);
+	}
+
+	return 0;
+}
+
+/**
+ * Get random number.
+ *
+ */
+uint16_t
+ldns_get_random(void)
+{
+        uint16_t rid = 0;
+#ifdef HAVE_SSL
+        if (RAND_bytes((unsigned char*)&rid, 2) != 1) {
+                rid = (uint16_t) random();
+        }
+#else
+        rid = (uint16_t) random();
+#endif
+	return rid;
+}
+
+/*
+ * BubbleBabble code taken from OpenSSH
+ * Copyright (c) 2001 Carsten Raskgaard.  All rights reserved.
+ */
+char *
+ldns_bubblebabble(uint8_t *data, size_t len)
+{
+	char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
+	char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
+	    'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
+	size_t i, j = 0, rounds, seed = 1;
+	char *retval;
+
+	rounds = (len / 2) + 1;
+	retval = LDNS_XMALLOC(char, rounds * 6);
+	if(!retval) return NULL;
+	retval[j++] = 'x';
+	for (i = 0; i < rounds; i++) {
+		size_t idx0, idx1, idx2, idx3, idx4;
+		if ((i + 1 < rounds) || (len % 2 != 0)) {
+			idx0 = (((((size_t)(data[2 * i])) >> 6) & 3) +
+			    seed) % 6;
+			idx1 = (((size_t)(data[2 * i])) >> 2) & 15;
+			idx2 = ((((size_t)(data[2 * i])) & 3) +
+			    (seed / 6)) % 6;
+			retval[j++] = vowels[idx0];
+			retval[j++] = consonants[idx1];
+			retval[j++] = vowels[idx2];
+			if ((i + 1) < rounds) {
+				idx3 = (((size_t)(data[(2 * i) + 1])) >> 4) & 15;
+				idx4 = (((size_t)(data[(2 * i) + 1]))) & 15;
+				retval[j++] = consonants[idx3];
+				retval[j++] = '-';
+				retval[j++] = consonants[idx4];
+				seed = ((seed * 5) +
+				    ((((size_t)(data[2 * i])) * 7) +
+				    ((size_t)(data[(2 * i) + 1])))) % 36;
+			}
+		} else {
+			idx0 = seed % 6;
+			idx1 = 16;
+			idx2 = seed / 6;
+			retval[j++] = vowels[idx0];
+			retval[j++] = consonants[idx1];
+			retval[j++] = vowels[idx2];
+		}
+	}
+	retval[j++] = 'x';
+	retval[j++] = '\0';
+	return retval;
+}
+
+/*
+ * For backwards compatibility, because we have always exported this symbol.
+ */
+#ifdef HAVE_B64_NTOP
+int ldns_b64_ntop(const uint8_t* src, size_t srclength,
+		char *target, size_t targsize);
+{
+	return b64_ntop(src, srclength, target, targsize);
+}
+#endif
+
+/*
+ * For backwards compatibility, because we have always exported this symbol.
+ */
+#ifdef HAVE_B64_PTON
+int ldns_b64_pton(const char* src, uint8_t *target, size_t targsize)
+{
+	return b64_pton(src, target, targsize);
+}
+#endif
+
+
+static int
+ldns_b32_ntop_base(const uint8_t* src, size_t src_sz,
+		char* dst, size_t dst_sz,
+		bool extended_hex, bool add_padding)
+{
+	size_t ret_sz;
+	const char* b32 = extended_hex ? "0123456789abcdefghijklmnopqrstuv"
+	                               : "abcdefghijklmnopqrstuvwxyz234567";
+
+	size_t c = 0; /* c is used to carry partial base32 character over 
+	               * byte boundaries for sizes with a remainder.
+		       * (i.e. src_sz % 5 != 0)
+		       */
+
+	ret_sz = add_padding ? ldns_b32_ntop_calculate_size(src_sz)
+	                     : ldns_b32_ntop_calculate_size_no_padding(src_sz);
+	
+	/* Do we have enough space? */
+	if (dst_sz < ret_sz + 1)
+		return -1;
+
+	/* We know the size; terminate the string */
+	dst[ret_sz] = '\0';
+
+	/* First process all chunks of five */
+	while (src_sz >= 5) {
+		/* 00000... ........ ........ ........ ........ */
+		dst[0] = b32[(src[0]       ) >> 3];
+
+		/* .....111 11...... ........ ........ ........ */
+		dst[1] = b32[(src[0] & 0x07) << 2 | src[1] >> 6];
+
+		/* ........ ..22222. ........ ........ ........ */
+		dst[2] = b32[(src[1] & 0x3e) >> 1];
+
+		/* ........ .......3 3333.... ........ ........ */
+		dst[3] = b32[(src[1] & 0x01) << 4 | src[2] >> 4];
+
+		/* ........ ........ ....4444 4....... ........ */
+		dst[4] = b32[(src[2] & 0x0f) << 1 | src[3] >> 7];
+
+		/* ........ ........ ........ .55555.. ........ */
+		dst[5] = b32[(src[3] & 0x7c) >> 2];
+
+		/* ........ ........ ........ ......66 666..... */
+		dst[6] = b32[(src[3] & 0x03) << 3 | src[4] >> 5];
+
+		/* ........ ........ ........ ........ ...77777 */
+		dst[7] = b32[(src[4] & 0x1f)     ];
+
+		src_sz -= 5;
+		src    += 5;
+		dst    += 8;
+	}
+	/* Process what remains */
+	switch (src_sz) {
+	case 4: /* ........ ........ ........ ......66 666..... */
+		dst[6] = b32[(src[3] & 0x03) << 3];
+
+		/* ........ ........ ........ .55555.. ........ */
+		dst[5] = b32[(src[3] & 0x7c) >> 2];
+
+		/* ........ ........ ....4444 4....... ........ */
+		         c =  src[3]         >> 7 ;
+	case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
+
+		/* ........ .......3 3333.... ........ ........ */
+			 c =  src[2]         >> 4 ;
+	case 2:	dst[3] = b32[(src[1] & 0x01) << 4 | c];
+
+		/* ........ ..22222. ........ ........ ........ */
+		dst[2] = b32[(src[1] & 0x3e) >> 1];
+
+		/* .....111 11...... ........ ........ ........ */
+	                 c =  src[1]         >> 6 ;
+	case 1:	dst[1] = b32[(src[0] & 0x07) << 2 | c];
+
+		/* 00000... ........ ........ ........ ........ */
+		dst[0] = b32[ src[0]         >> 3];
+	}
+	/* Add padding */
+	if (add_padding) {
+		switch (src_sz) {
+			case 1: dst[2] = '=';
+				dst[3] = '=';
+			case 2: dst[4] = '=';
+			case 3: dst[5] = '=';
+				dst[6] = '=';
+			case 4: dst[7] = '=';
+		}
+	}
+	return (int)ret_sz;
+}
+
+int 
+ldns_b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz)
+{
+	return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, false, true);
+}
+
+int 
+ldns_b32_ntop_extended_hex(const uint8_t* src, size_t src_sz,
+		char* dst, size_t dst_sz)
+{
+	return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, true, true);
+}
+
+#ifndef HAVE_B32_NTOP
+
+int 
+b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz)
+{
+	return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, false, true);
+}
+
+int 
+b32_ntop_extended_hex(const uint8_t* src, size_t src_sz,
+		char* dst, size_t dst_sz)
+{
+	return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, true, true);
+}
+
+#endif /* ! HAVE_B32_NTOP */
+
+static int
+ldns_b32_pton_base(const char* src, size_t src_sz,
+		uint8_t* dst, size_t dst_sz,
+		bool extended_hex, bool check_padding)
+{
+	size_t i = 0;
+	char ch = '\0';
+	uint8_t buf[8];
+	uint8_t* start = dst;
+
+	while (src_sz) {
+		/* Collect 8 characters in buf (if possible) */
+		for (i = 0; i < 8; i++) {
+
+			do {
+				ch = *src++;
+				--src_sz;
+
+			} while (isspace(ch) && src_sz > 0);
+
+			if (ch == '=' || ch == '\0')
+				break;
+
+			else if (extended_hex)
+
+				if (ch >= '0' && ch <= '9')
+					buf[i] = (uint8_t)ch - '0';
+				else if (ch >= 'a' && ch <= 'v')
+					buf[i] = (uint8_t)ch - 'a' + 10;
+				else if (ch >= 'A' && ch <= 'V')
+					buf[i] = (uint8_t)ch - 'A' + 10;
+				else
+					return -1;
+
+			else if (ch >= 'a' && ch <= 'z')
+				buf[i] = (uint8_t)ch - 'a';
+			else if (ch >= 'A' && ch <= 'Z')
+				buf[i] = (uint8_t)ch - 'A';
+			else if (ch >= '2' && ch <= '7')
+				buf[i] = (uint8_t)ch - '2' + 26;
+			else
+				return -1;
+		}
+		/* Less that 8 characters. We're done. */
+		if (i < 8)
+			break;
+
+		/* Enough space available at the destination? */
+		if (dst_sz < 5)
+			return -1;
+
+		/* 00000... ........ ........ ........ ........ */
+		/* .....111 11...... ........ ........ ........ */
+		dst[0] = buf[0] << 3 | buf[1] >> 2;
+
+		/* .....111 11...... ........ ........ ........ */
+		/* ........ ..22222. ........ ........ ........ */
+		/* ........ .......3 3333.... ........ ........ */
+		dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
+
+		/* ........ .......3 3333.... ........ ........ */
+		/* ........ ........ ....4444 4....... ........ */
+		dst[2] = buf[3] << 4 | buf[4] >> 1;
+
+		/* ........ ........ ....4444 4....... ........ */
+		/* ........ ........ ........ .55555.. ........ */
+		/* ........ ........ ........ ......66 666..... */
+		dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
+
+		/* ........ ........ ........ ......66 666..... */
+		/* ........ ........ ........ ........ ...77777 */
+		dst[4] = buf[6] << 5 | buf[7];
+
+		dst += 5;
+		dst_sz -= 5;
+	}
+	/* Not ending on a eight byte boundary? */
+	if (i > 0 && i < 8) {
+
+		/* Enough space available at the destination? */
+		if (dst_sz < (i + 1) / 2)
+			return -1;
+
+		switch (i) {
+		case 7: /* ........ ........ ........ ......66 666..... */
+			/* ........ ........ ........ .55555.. ........ */
+			/* ........ ........ ....4444 4....... ........ */
+			dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
+
+		case 5: /* ........ ........ ....4444 4....... ........ */
+			/* ........ .......3 3333.... ........ ........ */
+			dst[2] = buf[3] << 4 | buf[4] >> 1;
+
+		case 4: /* ........ .......3 3333.... ........ ........ */
+			/* ........ ..22222. ........ ........ ........ */
+			/* .....111 11...... ........ ........ ........ */
+			dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
+
+		case 2: /* .....111 11...... ........ ........ ........ */
+			/* 00000... ........ ........ ........ ........ */
+			dst[0] = buf[0] << 3 | buf[1] >> 2;
+
+			break;
+
+		default:
+			return -1;
+		}
+		dst += (i + 1) / 2;
+
+		if (check_padding) {
+			/* Check remaining padding characters */
+			if (ch != '=')
+				return -1;
+
+			/* One down, 8 - i - 1 more to come... */
+			for (i = 8 - i - 1; i > 0; i--) {
+
+				do {
+					if (src_sz == 0)
+						return -1;
+					ch = *src++;
+					src_sz--;
+
+				} while (isspace(ch));
+
+				if (ch != '=')
+					return -1;
+			}
+		}
+	}
+	return dst - start;
+}
+
+int
+ldns_b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz)
+{
+	return ldns_b32_pton_base(src, src_sz, dst, dst_sz, false, true);
+}
+
+int
+ldns_b32_pton_extended_hex(const char* src, size_t src_sz, 
+		uint8_t* dst, size_t dst_sz)
+{
+	return ldns_b32_pton_base(src, src_sz, dst, dst_sz, true, true);
+}
+
+#ifndef HAVE_B32_PTON
+
+int
+b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz)
+{
+	return ldns_b32_pton_base(src, src_sz, dst, dst_sz, false, true);
+}
+
+int
+b32_pton_extended_hex(const char* src, size_t src_sz, 
+		uint8_t* dst, size_t dst_sz)
+{
+	return ldns_b32_pton_base(src, src_sz, dst, dst_sz, true, true);
+}
+
+#endif /* ! HAVE_B32_PTON */
+
diff --git a/ldns/src/wire2host.c b/ldns/src/wire2host.c
new file mode 100644
index 0000000..e492215
--- /dev/null
+++ b/ldns/src/wire2host.c
@@ -0,0 +1,491 @@
+/*
+ * wire2host.c
+ *
+ * conversion routines from the wire to the host
+ * format.
+ * This will usually just a re-ordering of the
+ * data (as we store it in network format)
+ *
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2004-2006
+ *
+ * See the file LICENSE for the license
+ */
+
+
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+/*#include <ldns/wire2host.h>*/
+
+#include <strings.h>
+#include <limits.h>
+
+
+
+/*
+ * Set of macro's to deal with the dns message header as specified
+ * in RFC1035 in portable way.
+ *
+ */
+
+/*
+ *
+ *                                    1  1  1  1  1  1
+ *      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+ *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *    |                      ID                       |
+ *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *    |QR|   Opcode  |AA|TC|RD|RA| Z|AD|CD|   RCODE   |
+ *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *    |                    QDCOUNT                    |
+ *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *    |                    ANCOUNT                    |
+ *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *    |                    NSCOUNT                    |
+ *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *    |                    ARCOUNT                    |
+ *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *
+ */
+
+
+/* allocates memory to *dname! */
+ldns_status
+ldns_wire2dname(ldns_rdf **dname, const uint8_t *wire, size_t max, size_t *pos)
+{
+	uint8_t label_size;
+	uint16_t pointer_target;
+	uint8_t pointer_target_buf[2];
+	size_t dname_pos = 0;
+	size_t uncompressed_length = 0;
+	size_t compression_pos = 0;
+	uint8_t tmp_dname[LDNS_MAX_DOMAINLEN];
+	unsigned int pointer_count = 0;
+
+	if (pos == NULL) {
+		return LDNS_STATUS_WIRE_RDATA_ERR;
+	}
+	if (*pos >= max) {
+		return LDNS_STATUS_PACKET_OVERFLOW;
+	}
+	label_size = wire[*pos];
+	while (label_size > 0) {
+		/* compression */
+		while (label_size >= 192) {
+			if (compression_pos == 0) {
+				compression_pos = *pos + 2;
+			}
+
+			pointer_count++;
+
+			/* remove first two bits */
+			if (*pos + 2 > max) {
+				return LDNS_STATUS_PACKET_OVERFLOW;
+			}
+			pointer_target_buf[0] = wire[*pos] & 63;
+			pointer_target_buf[1] = wire[*pos + 1];
+			pointer_target = ldns_read_uint16(pointer_target_buf);
+
+			if (pointer_target == 0) {
+				return LDNS_STATUS_INVALID_POINTER;
+			} else if (pointer_target >= max) {
+				return LDNS_STATUS_INVALID_POINTER;
+			} else if (pointer_count > LDNS_MAX_POINTERS) {
+				return LDNS_STATUS_INVALID_POINTER;
+			}
+			*pos = pointer_target;
+			label_size = wire[*pos];
+		}
+		if(label_size == 0)
+			break; /* break from pointer to 0 byte */
+		if (label_size > LDNS_MAX_LABELLEN) {
+			return LDNS_STATUS_LABEL_OVERFLOW;
+		}
+		if (*pos + 1 + label_size > max) {
+			return LDNS_STATUS_LABEL_OVERFLOW;
+		}
+
+		/* check space for labelcount itself */
+		if (dname_pos + 1 > LDNS_MAX_DOMAINLEN) {
+			return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+		}
+		tmp_dname[dname_pos] = label_size;
+		if (label_size > 0) {
+			dname_pos++;
+		}
+		*pos = *pos + 1;
+		if (dname_pos + label_size > LDNS_MAX_DOMAINLEN) {
+			return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+		}
+		memcpy(&tmp_dname[dname_pos], &wire[*pos], label_size);
+		uncompressed_length += label_size + 1;
+		dname_pos += label_size;
+		*pos = *pos + label_size;
+
+		if (*pos < max) {
+			label_size = wire[*pos];
+		}
+	}
+
+	if (compression_pos > 0) {
+		*pos = compression_pos;
+	} else {
+		*pos = *pos + 1;
+	}
+
+	if (dname_pos >= LDNS_MAX_DOMAINLEN) {
+		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
+	}
+
+	tmp_dname[dname_pos] = 0;
+	dname_pos++;
+
+	*dname = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
+			(uint16_t) dname_pos, tmp_dname);
+	if (!*dname) {
+		return LDNS_STATUS_MEM_ERR;
+	}
+	return LDNS_STATUS_OK;
+}
+
+/* maybe make this a goto error so data can be freed or something/ */
+#define LDNS_STATUS_CHECK_RETURN(st) {if (st != LDNS_STATUS_OK) { return st; }}
+#define LDNS_STATUS_CHECK_GOTO(st, label) {if (st != LDNS_STATUS_OK) { /*printf("STG %s:%d: status code %d\n", __FILE__, __LINE__, st);*/  goto label; }}
+
+ldns_status
+ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos)
+{
+	size_t end;
+	size_t cur_rdf_length;
+	uint8_t rdf_index;
+	uint8_t *data;
+	uint16_t rd_length;
+	ldns_rdf *cur_rdf = NULL;
+	ldns_rdf_type cur_rdf_type;
+	const ldns_rr_descriptor *descriptor;
+	ldns_status status;
+
+	assert(rr != NULL);
+
+	descriptor = ldns_rr_descript(ldns_rr_get_type(rr));
+
+	if (*pos + 2 > max) {
+		return LDNS_STATUS_PACKET_OVERFLOW;
+	}
+
+	rd_length = ldns_read_uint16(&wire[*pos]);
+	*pos = *pos + 2;
+
+	if (*pos + rd_length > max) {
+		return LDNS_STATUS_PACKET_OVERFLOW;
+	}
+
+	end = *pos + (size_t) rd_length;
+
+	rdf_index = 0;
+	while (*pos < end &&
+			rdf_index < ldns_rr_descriptor_maximum(descriptor)) {
+
+		cur_rdf_length = 0;
+
+		cur_rdf_type = ldns_rr_descriptor_field_type(
+				descriptor, rdf_index);
+
+		/* handle special cases immediately, set length
+		   for fixed length rdata and do them below */
+		switch (cur_rdf_type) {
+		case LDNS_RDF_TYPE_DNAME:
+			status = ldns_wire2dname(&cur_rdf, wire, max, pos);
+			LDNS_STATUS_CHECK_RETURN(status);
+			break;
+		case LDNS_RDF_TYPE_CLASS:
+		case LDNS_RDF_TYPE_ALG:
+		case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
+		case LDNS_RDF_TYPE_SELECTOR:
+		case LDNS_RDF_TYPE_MATCHING_TYPE:
+		case LDNS_RDF_TYPE_INT8:
+			cur_rdf_length = LDNS_RDF_SIZE_BYTE;
+			break;
+		case LDNS_RDF_TYPE_TYPE:
+		case LDNS_RDF_TYPE_INT16:
+		case LDNS_RDF_TYPE_CERT_ALG:
+			cur_rdf_length = LDNS_RDF_SIZE_WORD;
+			break;
+		case LDNS_RDF_TYPE_TIME:
+		case LDNS_RDF_TYPE_INT32:
+		case LDNS_RDF_TYPE_A:
+		case LDNS_RDF_TYPE_PERIOD:
+			cur_rdf_length = LDNS_RDF_SIZE_DOUBLEWORD;
+			break;
+		case LDNS_RDF_TYPE_TSIGTIME:
+		case LDNS_RDF_TYPE_EUI48:
+			cur_rdf_length = LDNS_RDF_SIZE_6BYTES;
+			break;
+		case LDNS_RDF_TYPE_ILNP64:
+		case LDNS_RDF_TYPE_EUI64:
+			cur_rdf_length = LDNS_RDF_SIZE_8BYTES;
+			break;
+		case LDNS_RDF_TYPE_AAAA:
+			cur_rdf_length = LDNS_RDF_SIZE_16BYTES;
+			break;
+		case LDNS_RDF_TYPE_STR:
+		case LDNS_RDF_TYPE_NSEC3_SALT:
+		case LDNS_RDF_TYPE_TAG:
+			/* len is stored in first byte
+			 * it should be in the rdf too, so just
+			 * copy len+1 from this position
+			 */
+			cur_rdf_length = ((size_t) wire[*pos]) + 1;
+			break;
+
+		case LDNS_RDF_TYPE_INT16_DATA:
+			if (*pos + 2 > end) {
+				return LDNS_STATUS_PACKET_OVERFLOW;
+			}
+			cur_rdf_length =
+				(size_t) ldns_read_uint16(&wire[*pos]) + 2;
+			break;
+		case LDNS_RDF_TYPE_HIP:
+			if (*pos + 4 > end) {
+				return LDNS_STATUS_PACKET_OVERFLOW;
+			}
+			cur_rdf_length =
+				(size_t) wire[*pos] + 
+				(size_t) ldns_read_uint16(&wire[*pos + 2]) + 4;
+			break;
+		case LDNS_RDF_TYPE_B32_EXT:
+		case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
+			/* length is stored in first byte */
+			cur_rdf_length = ((size_t) wire[*pos]) + 1;
+			break;
+		case LDNS_RDF_TYPE_APL:
+		case LDNS_RDF_TYPE_B64:
+		case LDNS_RDF_TYPE_HEX:
+		case LDNS_RDF_TYPE_NSEC:
+		case LDNS_RDF_TYPE_UNKNOWN:
+		case LDNS_RDF_TYPE_SERVICE:
+		case LDNS_RDF_TYPE_LOC:
+		case LDNS_RDF_TYPE_WKS:
+		case LDNS_RDF_TYPE_NSAP:
+		case LDNS_RDF_TYPE_ATMA:
+		case LDNS_RDF_TYPE_IPSECKEY:
+		case LDNS_RDF_TYPE_LONG_STR:
+		case LDNS_RDF_TYPE_NONE:
+			/*
+			 * Read to end of rr rdata
+			 */
+			cur_rdf_length = end - *pos;
+			break;
+		}
+
+		/* fixed length rdata */
+		if (cur_rdf_length > 0) {
+			if (cur_rdf_length + *pos > end) {
+				return LDNS_STATUS_PACKET_OVERFLOW;
+			}
+			data = LDNS_XMALLOC(uint8_t, rd_length);
+			if (!data) {
+				return LDNS_STATUS_MEM_ERR;
+			}
+			memcpy(data, &wire[*pos], cur_rdf_length);
+
+			cur_rdf = ldns_rdf_new(cur_rdf_type,
+					cur_rdf_length, data);
+			*pos = *pos + cur_rdf_length;
+		}
+
+		if (cur_rdf) {
+			ldns_rr_push_rdf(rr, cur_rdf);
+			cur_rdf = NULL;
+		}
+
+		rdf_index++;
+
+	} /* while (rdf_index < ldns_rr_descriptor_maximum(descriptor)) */
+
+
+	return LDNS_STATUS_OK;
+}
+
+
+/* TODO:
+         can *pos be incremented at READ_INT? or maybe use something like
+         RR_CLASS(wire)?
+	 uhhm Jelte??
+*/
+ldns_status
+ldns_wire2rr(ldns_rr **rr_p, const uint8_t *wire, size_t max,
+             size_t *pos, ldns_pkt_section section)
+{
+	ldns_rdf *owner = NULL;
+	ldns_rr *rr = ldns_rr_new();
+	ldns_status status;
+
+	status = ldns_wire2dname(&owner, wire, max, pos);
+	LDNS_STATUS_CHECK_GOTO(status, status_error);
+
+	ldns_rr_set_owner(rr, owner);
+
+	if (*pos + 4 > max) {
+		status = LDNS_STATUS_PACKET_OVERFLOW;
+		goto status_error;
+	}
+
+	ldns_rr_set_type(rr, ldns_read_uint16(&wire[*pos]));
+	*pos = *pos + 2;
+
+	ldns_rr_set_class(rr, ldns_read_uint16(&wire[*pos]));
+	*pos = *pos + 2;
+
+	if (section != LDNS_SECTION_QUESTION) {
+		if (*pos + 4 > max) {
+			status = LDNS_STATUS_PACKET_OVERFLOW;
+			goto status_error;
+		}
+		ldns_rr_set_ttl(rr, ldns_read_uint32(&wire[*pos]));
+
+		*pos = *pos + 4;
+		status = ldns_wire2rdf(rr, wire, max, pos);
+
+		LDNS_STATUS_CHECK_GOTO(status, status_error);
+        ldns_rr_set_question(rr, false);
+	} else {
+        ldns_rr_set_question(rr, true);
+    }
+
+	*rr_p = rr;
+	return LDNS_STATUS_OK;
+
+status_error:
+	ldns_rr_free(rr);
+	return status;
+}
+
+static ldns_status
+ldns_wire2pkt_hdr(ldns_pkt *packet, const uint8_t *wire, size_t max, size_t *pos)
+{
+	if (*pos + LDNS_HEADER_SIZE > max) {
+		return LDNS_STATUS_WIRE_INCOMPLETE_HEADER;
+	} else {
+		ldns_pkt_set_id(packet, LDNS_ID_WIRE(wire));
+		ldns_pkt_set_qr(packet, LDNS_QR_WIRE(wire));
+		ldns_pkt_set_opcode(packet, LDNS_OPCODE_WIRE(wire));
+		ldns_pkt_set_aa(packet, LDNS_AA_WIRE(wire));
+		ldns_pkt_set_tc(packet, LDNS_TC_WIRE(wire));
+		ldns_pkt_set_rd(packet, LDNS_RD_WIRE(wire));
+		ldns_pkt_set_ra(packet, LDNS_RA_WIRE(wire));
+		ldns_pkt_set_ad(packet, LDNS_AD_WIRE(wire));
+		ldns_pkt_set_cd(packet, LDNS_CD_WIRE(wire));
+		ldns_pkt_set_rcode(packet, LDNS_RCODE_WIRE(wire));
+
+		ldns_pkt_set_qdcount(packet, LDNS_QDCOUNT(wire));
+		ldns_pkt_set_ancount(packet, LDNS_ANCOUNT(wire));
+		ldns_pkt_set_nscount(packet, LDNS_NSCOUNT(wire));
+		ldns_pkt_set_arcount(packet, LDNS_ARCOUNT(wire));
+
+		*pos += LDNS_HEADER_SIZE;
+
+		return LDNS_STATUS_OK;
+	}
+}
+
+ldns_status
+ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer)
+{
+	/* lazy */
+	return ldns_wire2pkt(packet, ldns_buffer_begin(buffer),
+				ldns_buffer_limit(buffer));
+
+}
+
+ldns_status
+ldns_wire2pkt(ldns_pkt **packet_p, const uint8_t *wire, size_t max)
+{
+	size_t pos = 0;
+	uint16_t i;
+	ldns_rr *rr;
+	ldns_pkt *packet = ldns_pkt_new();
+	ldns_status status = LDNS_STATUS_OK;
+	uint8_t have_edns = 0;
+
+	uint8_t data[4];
+
+	status = ldns_wire2pkt_hdr(packet, wire, max, &pos);
+	LDNS_STATUS_CHECK_GOTO(status, status_error);
+
+	for (i = 0; i < ldns_pkt_qdcount(packet); i++) {
+
+		status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_QUESTION);
+		if (status == LDNS_STATUS_PACKET_OVERFLOW) {
+			status = LDNS_STATUS_WIRE_INCOMPLETE_QUESTION;
+		}
+		LDNS_STATUS_CHECK_GOTO(status, status_error);
+		if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
+			ldns_pkt_free(packet);
+			return LDNS_STATUS_INTERNAL_ERR;
+		}
+	}
+	for (i = 0; i < ldns_pkt_ancount(packet); i++) {
+		status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_ANSWER);
+		if (status == LDNS_STATUS_PACKET_OVERFLOW) {
+			status = LDNS_STATUS_WIRE_INCOMPLETE_ANSWER;
+		}
+		LDNS_STATUS_CHECK_GOTO(status, status_error);
+		if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
+			ldns_pkt_free(packet);
+			return LDNS_STATUS_INTERNAL_ERR;
+		}
+	}
+	for (i = 0; i < ldns_pkt_nscount(packet); i++) {
+		status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_AUTHORITY);
+		if (status == LDNS_STATUS_PACKET_OVERFLOW) {
+			status = LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY;
+		}
+		LDNS_STATUS_CHECK_GOTO(status, status_error);
+		if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
+			ldns_pkt_free(packet);
+			return LDNS_STATUS_INTERNAL_ERR;
+		}
+	}
+	for (i = 0; i < ldns_pkt_arcount(packet); i++) {
+		status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_ADDITIONAL);
+		if (status == LDNS_STATUS_PACKET_OVERFLOW) {
+			status = LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL;
+		}
+		LDNS_STATUS_CHECK_GOTO(status, status_error);
+
+		if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_OPT) {
+			ldns_pkt_set_edns_udp_size(packet, ldns_rr_get_class(rr));
+			ldns_write_uint32(data, ldns_rr_ttl(rr));
+			ldns_pkt_set_edns_extended_rcode(packet, data[0]);
+			ldns_pkt_set_edns_version(packet, data[1]);
+			ldns_pkt_set_edns_z(packet, ldns_read_uint16(&data[2]));
+			/* edns might not have rdfs */
+			if (ldns_rr_rdf(rr, 0)) {
+				ldns_pkt_set_edns_data(packet, ldns_rdf_clone(ldns_rr_rdf(rr, 0)));
+			}
+			ldns_rr_free(rr);
+			have_edns += 1;
+		} else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_TSIG) {
+			ldns_pkt_set_tsig(packet, rr);
+			ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) - 1);
+		} else if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
+			ldns_pkt_free(packet);
+			return LDNS_STATUS_INTERNAL_ERR;
+		}
+	}
+	ldns_pkt_set_size(packet, max);
+	if(have_edns)
+		ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet)
+                        - have_edns);
+        packet->_edns_present = have_edns;
+
+	*packet_p = packet;
+	return status;
+
+status_error:
+	ldns_pkt_free(packet);
+	return status;
+}
diff --git a/ldns/src/zone.c b/ldns/src/zone.c
new file mode 100644
index 0000000..d97a81e
--- /dev/null
+++ b/ldns/src/zone.c
@@ -0,0 +1,318 @@
+/* zone.c
+ *
+ * Functions for ldns_zone structure
+ * a Net::DNS like library for C
+ *
+ * (c) NLnet Labs, 2005-2006
+ * See the file LICENSE for the license
+ */
+#include <ldns/config.h>
+
+#include <ldns/ldns.h>
+
+#include <strings.h>
+#include <limits.h>
+
+ldns_rr *
+ldns_zone_soa(const ldns_zone *z)
+{
+        return z->_soa;
+}
+
+size_t
+ldns_zone_rr_count(const ldns_zone *z)
+{
+	return ldns_rr_list_rr_count(z->_rrs);
+}
+
+void
+ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa)
+{
+	z->_soa = soa;
+}
+
+ldns_rr_list *
+ldns_zone_rrs(const ldns_zone *z)
+{
+	return z->_rrs;
+}
+
+void
+ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist)
+{
+	z->_rrs = rrlist;
+}
+
+bool
+ldns_zone_push_rr_list(ldns_zone *z, ldns_rr_list *list)
+{
+	return ldns_rr_list_cat(ldns_zone_rrs(z), list);
+
+}
+
+bool
+ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
+{
+	return ldns_rr_list_push_rr( ldns_zone_rrs(z), rr);
+}
+
+
+/*
+ * Get the list of glue records in a zone
+ * XXX: there should be a way for this to return error, other than NULL, 
+ *      since NULL is a valid return
+ */
+ldns_rr_list *
+ldns_zone_glue_rr_list(const ldns_zone *z)
+{
+	/* when do we find glue? It means we find an IP address
+	 * (AAAA/A) for a nameserver listed in the zone
+	 *
+	 * Alg used here:
+	 * first find all the zonecuts (NS records)
+	 * find all the AAAA or A records (can be done it the 
+	 * above loop).
+	 *
+	 * Check if the aaaa/a list are subdomains under the
+	 * NS domains.
+	 * If yes -> glue, if no -> not glue
+	 */
+
+	ldns_rr_list *zone_cuts;
+	ldns_rr_list *addr;
+	ldns_rr_list *glue;
+	ldns_rr *r, *ns, *a;
+	ldns_rdf *dname_a, *ns_owner;
+	size_t i,j;
+
+	zone_cuts = NULL;
+	addr = NULL;
+	glue = NULL;
+
+	/* we cannot determine glue in a 'zone' without a SOA */
+	if (!ldns_zone_soa(z)) {
+		return NULL;
+	}
+
+	zone_cuts = ldns_rr_list_new();
+	if (!zone_cuts) goto memory_error;
+	addr = ldns_rr_list_new();
+	if (!addr) goto memory_error;
+	glue = ldns_rr_list_new();
+	if (!glue) goto memory_error;
+
+	for(i = 0; i < ldns_zone_rr_count(z); i++) {
+		r = ldns_rr_list_rr(ldns_zone_rrs(z), i);
+		if (ldns_rr_get_type(r) == LDNS_RR_TYPE_A ||
+				ldns_rr_get_type(r) == LDNS_RR_TYPE_AAAA) {
+			/* possibly glue */
+			if (!ldns_rr_list_push_rr(addr, r)) goto memory_error;
+			continue;
+		}
+		if (ldns_rr_get_type(r) == LDNS_RR_TYPE_NS) {
+			/* multiple zones will end up here -
+			 * for now; not a problem
+			 */
+			/* don't add NS records for the current zone itself */
+			if (ldns_rdf_compare(ldns_rr_owner(r), 
+						ldns_rr_owner(ldns_zone_soa(z))) != 0) {
+				if (!ldns_rr_list_push_rr(zone_cuts, r)) goto memory_error;
+			}
+			continue;
+		}
+	}
+
+	/* will sorting make it quicker ?? */
+	for(i = 0; i < ldns_rr_list_rr_count(zone_cuts); i++) {
+		ns = ldns_rr_list_rr(zone_cuts, i);
+		ns_owner = ldns_rr_owner(ns);
+
+		for(j = 0; j < ldns_rr_list_rr_count(addr); j++) {
+			a = ldns_rr_list_rr(addr, j);
+			dname_a = ldns_rr_owner(a);
+
+			if (ldns_dname_is_subdomain(dname_a, ns_owner) ||
+				ldns_dname_compare(dname_a, ns_owner) == 0) {
+				/* GLUE! */
+				if (!ldns_rr_list_push_rr(glue, a)) goto memory_error;
+			}
+		}
+	}
+	
+	ldns_rr_list_free(addr);
+	ldns_rr_list_free(zone_cuts);
+
+	if (ldns_rr_list_rr_count(glue) == 0) {
+		ldns_rr_list_free(glue);
+		return NULL;
+	} else {
+		return glue;
+	}
+
+memory_error:
+	if (zone_cuts) {
+		LDNS_FREE(zone_cuts);
+	}
+	if (addr) {
+		ldns_rr_list_free(addr);
+	}
+	if (glue) {
+		ldns_rr_list_free(glue);
+	}
+	return NULL;
+}
+
+ldns_zone *
+ldns_zone_new(void)
+{
+	ldns_zone *z;
+
+	z = LDNS_MALLOC(ldns_zone);
+	if (!z) {
+		return NULL;
+	}
+
+	z->_rrs = ldns_rr_list_new();
+	if (!z->_rrs) {
+		LDNS_FREE(z);
+		return NULL;
+	}
+	ldns_zone_set_soa(z, NULL);
+	return z;
+}
+
+/* we regocnize:
+ * $TTL, $ORIGIN
+ */
+ldns_status
+ldns_zone_new_frm_fp(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c)
+{
+	return ldns_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
+}
+
+/* XXX: class is never used */
+ldns_status
+ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, 
+        ldns_rr_class ATTR_UNUSED(c), int *line_nr)
+{
+	ldns_zone *newzone;
+	ldns_rr *rr;
+	uint32_t my_ttl;
+	ldns_rdf *my_origin;
+	ldns_rdf *my_prev;
+	bool soa_seen = false; 	/* 2 soa are an error */
+	ldns_status s;
+	ldns_status ret;
+
+	/* most cases of error are memory problems */
+	ret = LDNS_STATUS_MEM_ERR;
+
+	newzone = NULL;
+	my_origin = NULL;
+	my_prev = NULL;
+
+	my_ttl    = ttl;
+	
+	if (origin) {
+		my_origin = ldns_rdf_clone(origin);
+		if (!my_origin) goto error;
+		/* also set the prev */
+		my_prev   = ldns_rdf_clone(origin);
+		if (!my_prev) goto error;
+	}
+
+	newzone = ldns_zone_new();
+	if (!newzone) goto error;
+
+	while(!feof(fp)) {
+		s = ldns_rr_new_frm_fp_l(&rr, fp, &my_ttl, &my_origin, &my_prev, line_nr);
+		switch (s) {
+		case LDNS_STATUS_OK:
+			if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
+				if (soa_seen) {
+					/* second SOA 
+					 * just skip, maybe we want to say
+					 * something??? */
+					ldns_rr_free(rr);
+					continue;
+				}
+				soa_seen = true;
+				ldns_zone_set_soa(newzone, rr);
+				/* set origin to soa if not specified */
+				if (!my_origin) {
+					my_origin = ldns_rdf_clone(ldns_rr_owner(rr));
+				}
+				continue;
+			}
+			
+			/* a normal RR - as sofar the DNS is normal */
+			if (!ldns_zone_push_rr(newzone, rr)) goto error;
+
+		case LDNS_STATUS_SYNTAX_EMPTY:
+			/* empty line was seen */
+		case LDNS_STATUS_SYNTAX_TTL:
+			/* the function set the ttl */
+			break;
+		case LDNS_STATUS_SYNTAX_ORIGIN:
+			/* the function set the origin */
+			break;
+		case LDNS_STATUS_SYNTAX_INCLUDE:
+			ret = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
+			break;
+		default:
+			ret = s;
+			goto error;
+		}
+	}
+
+	if (my_origin) {
+		ldns_rdf_deep_free(my_origin);
+	}
+	if (my_prev) {
+		ldns_rdf_deep_free(my_prev);
+	}
+	if (z) {
+		*z = newzone;
+	} else {
+		ldns_zone_free(newzone);
+	}
+
+	return LDNS_STATUS_OK;
+
+error:
+	if (my_origin) {
+		ldns_rdf_deep_free(my_origin);
+	}
+	if (my_prev) {
+		ldns_rdf_deep_free(my_prev);
+	}
+	if (newzone) {
+		ldns_zone_free(newzone);
+	}
+	return ret;
+}
+
+void
+ldns_zone_sort(ldns_zone *zone)
+{
+	ldns_rr_list *zrr;
+	assert(zone != NULL);
+
+	zrr = ldns_zone_rrs(zone);
+	ldns_rr_list_sort(zrr);
+}
+
+void
+ldns_zone_free(ldns_zone *zone) 
+{
+	ldns_rr_list_free(zone->_rrs);
+	LDNS_FREE(zone);
+}
+
+void
+ldns_zone_deep_free(ldns_zone *zone) 
+{
+	ldns_rr_free(zone->_soa);
+	ldns_rr_list_deep_free(zone->_rrs);
+	LDNS_FREE(zone);
+}
diff --git a/src/ldns/buffer.c b/src/ldns/buffer.c
deleted file mode 100644
index fc6c17e..0000000
--- a/src/ldns/buffer.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * buffer.c -- generic memory buffer .
- *
- * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- *
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-#include <ldns/buffer.h>
-
-ldns_buffer *
-ldns_buffer_new(size_t capacity)
-{
-	ldns_buffer *buffer = LDNS_MALLOC(ldns_buffer);
-
-	if (!buffer) {
-		return NULL;
-	}
-	
-	buffer->_data = (uint8_t *) LDNS_XMALLOC(uint8_t, capacity);
-	if (!buffer->_data) {
-		LDNS_FREE(buffer);
-		return NULL;
-	}
-	
-	buffer->_position = 0;
-	buffer->_limit = buffer->_capacity = capacity;
-	buffer->_fixed = 0;
-	buffer->_status = LDNS_STATUS_OK;
-	
-	ldns_buffer_invariant(buffer);
-	
-	return buffer;
-}
-
-void
-ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
-{
-	assert(data != NULL);
-
-	buffer->_position = 0; 
-	buffer->_limit = buffer->_capacity = size;
-	buffer->_fixed = 0;
-	buffer->_data = LDNS_XMALLOC(uint8_t, size);
-	if(!buffer->_data) {
-		buffer->_status = LDNS_STATUS_MEM_ERR;
-		return;
-	}
-	memcpy(buffer->_data, data, size);
-	buffer->_status = LDNS_STATUS_OK;
-	
-	ldns_buffer_invariant(buffer);
-}
-
-bool
-ldns_buffer_set_capacity(ldns_buffer *buffer, size_t capacity)
-{
-	void *data;
-	
-	ldns_buffer_invariant(buffer);
-	assert(buffer->_position <= capacity);
-
-	data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
-	if (!data) {
-		buffer->_status = LDNS_STATUS_MEM_ERR;
-		return false;
-	} else {
-		buffer->_data = data;
-		buffer->_limit = buffer->_capacity = capacity;
-		return true;
-	}
-}
-
-bool
-ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
-{
-	ldns_buffer_invariant(buffer);
-	assert(!buffer->_fixed);
-	if (buffer->_capacity < buffer->_position + amount) {
-		size_t new_capacity = buffer->_capacity * 3 / 2;
-
-		if (new_capacity < buffer->_position + amount) {
-			new_capacity = buffer->_position + amount;
-		}
-		if (!ldns_buffer_set_capacity(buffer, new_capacity)) {
-			buffer->_status = LDNS_STATUS_MEM_ERR;
-			return false;
-		}
-	}
-	buffer->_limit = buffer->_capacity;
-	return true;
-}
-
-int
-ldns_buffer_printf(ldns_buffer *buffer, const char *format, ...)
-{
-	va_list args;
-	int written = 0;
-	size_t remaining;
-	
-	if (ldns_buffer_status_ok(buffer)) {
-		ldns_buffer_invariant(buffer);
-		assert(buffer->_limit == buffer->_capacity);
-
-		remaining = ldns_buffer_remaining(buffer);
-		va_start(args, format);
-		written = vsnprintf((char *) ldns_buffer_current(buffer), remaining,
-				    format, args);
-		va_end(args);
-		if (written == -1) {
-			buffer->_status = LDNS_STATUS_INTERNAL_ERR;
-			return -1;
-		} else if ((size_t) written >= remaining) {
-			if (!ldns_buffer_reserve(buffer, (size_t) written + 1)) {
-				buffer->_status = LDNS_STATUS_MEM_ERR;
-				return -1;
-			}
-			va_start(args, format);
-			written = vsnprintf((char *) ldns_buffer_current(buffer),
-			    ldns_buffer_remaining(buffer), format, args);
-			va_end(args);
-			if (written == -1) {
-				buffer->_status = LDNS_STATUS_INTERNAL_ERR;
-				return -1;
-			}
-		}
-		buffer->_position += written;
-	}
-	return written;
-}
-
-void
-ldns_buffer_free(ldns_buffer *buffer)
-{
-	if (!buffer) {
-		return;
-	}
-
-	if (!buffer->_fixed)
-		LDNS_FREE(buffer->_data);
-
-	LDNS_FREE(buffer);
-}
-
-void *
-ldns_buffer_export(ldns_buffer *buffer)
-{
-	buffer->_fixed = 1;
-	return buffer->_data;
-}
-
-int
-ldns_bgetc(ldns_buffer *buffer)
-{
-	if (!ldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) {
-		ldns_buffer_set_position(buffer, ldns_buffer_limit(buffer));
-		/* ldns_buffer_rewind(buffer);*/
-		return EOF;
-	}
-	return (int)ldns_buffer_read_u8(buffer);
-}
-
-void 
-ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
-{
-	size_t tocopy = ldns_buffer_limit(from);
-
-	if(tocopy > ldns_buffer_capacity(result))
-		tocopy = ldns_buffer_capacity(result);
-	ldns_buffer_clear(result);
-	ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
-	ldns_buffer_flip(result);
-}
diff --git a/src/ldns/compat/b64_ntop.c b/src/ldns/compat/b64_ntop.c
deleted file mode 100644
index 6895aca..0000000
--- a/src/ldns/compat/b64_ntop.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (c) 1996, 1998 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/*
- * Portions Copyright (c) 1995 by International Business Machines, Inc.
- *
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
- *
- * To the extent it has a right to do so, IBM grants an immunity from suit
- * under its patents, if any, for the use, sale or manufacture of products to
- * the extent that such products are used for performing Domain Name System
- * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
- * granted for any product per se or for any other function of any product.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- */
-#include <ldns/config.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-static const char Base64[] =
-	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static const char Pad64 = '=';
-
-/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
-   The following encoding technique is taken from RFC 1521 by Borenstein
-   and Freed.  It is reproduced here in a slightly edited form for
-   convenience.
-
-   A 65-character subset of US-ASCII is used, enabling 6 bits to be
-   represented per printable character. (The extra 65th character, "=",
-   is used to signify a special processing function.)
-
-   The encoding process represents 24-bit groups of input bits as output
-   strings of 4 encoded characters. Proceeding from left to right, a
-   24-bit input group is formed by concatenating 3 8-bit input groups.
-   These 24 bits are then treated as 4 concatenated 6-bit groups, each
-   of which is translated into a single digit in the base64 alphabet.
-
-   Each 6-bit group is used as an index into an array of 64 printable
-   characters. The character referenced by the index is placed in the
-   output string.
-
-                         Table 1: The Base64 Alphabet
-
-      Value Encoding  Value Encoding  Value Encoding  Value Encoding
-          0 A            17 R            34 i            51 z
-          1 B            18 S            35 j            52 0
-          2 C            19 T            36 k            53 1
-          3 D            20 U            37 l            54 2
-          4 E            21 V            38 m            55 3
-          5 F            22 W            39 n            56 4
-          6 G            23 X            40 o            57 5
-          7 H            24 Y            41 p            58 6
-          8 I            25 Z            42 q            59 7
-          9 J            26 a            43 r            60 8
-         10 K            27 b            44 s            61 9
-         11 L            28 c            45 t            62 +
-         12 M            29 d            46 u            63 /
-         13 N            30 e            47 v
-         14 O            31 f            48 w         (pad) =
-         15 P            32 g            49 x
-         16 Q            33 h            50 y
-
-   Special processing is performed if fewer than 24 bits are available
-   at the end of the data being encoded.  A full encoding quantum is
-   always completed at the end of a quantity.  When fewer than 24 input
-   bits are available in an input group, zero bits are added (on the
-   right) to form an integral number of 6-bit groups.  Padding at the
-   end of the data is performed using the '=' character.
-
-   Since all base64 input is an integral number of octets, only the
-         -------------------------------------------------                       
-   following cases can arise:
-   
-       (1) the final quantum of encoding input is an integral
-           multiple of 24 bits; here, the final unit of encoded
-	   output will be an integral multiple of 4 characters
-	   with no "=" padding,
-       (2) the final quantum of encoding input is exactly 8 bits;
-           here, the final unit of encoded output will be two
-	   characters followed by two "=" padding characters, or
-       (3) the final quantum of encoding input is exactly 16 bits;
-           here, the final unit of encoded output will be three
-	   characters followed by one "=" padding character.
-   */
-
-int
-ldns_b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
-	size_t datalength = 0;
-	uint8_t input[3];
-	uint8_t output[4];
-	size_t i;
-	
-	if (srclength == 0) {
-		if (targsize > 0) {
-			target[0] = '\0';
-			return 0;
-		} else {
-			return -1;
-		}
-	}
-
-	while (2 < srclength) {
-		input[0] = *src++;
-		input[1] = *src++;
-		input[2] = *src++;
-		srclength -= 3;
-
-		output[0] = input[0] >> 2;
-		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
-		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
-		output[3] = input[2] & 0x3f;
-		assert(output[0] < 64);
-		assert(output[1] < 64);
-		assert(output[2] < 64);
-		assert(output[3] < 64);
-
-		if (datalength + 4 > targsize) {
-			return (-1);
-		}
-		target[datalength++] = Base64[output[0]];
-		target[datalength++] = Base64[output[1]];
-		target[datalength++] = Base64[output[2]];
-		target[datalength++] = Base64[output[3]];
-	}
-    
-	/* Now we worry about padding. */
-	if (0 != srclength) {
-		/* Get what's left. */
-		input[0] = input[1] = input[2] = (uint8_t) '\0';
-		for (i = 0; i < srclength; i++)
-			input[i] = *src++;
-	
-		output[0] = input[0] >> 2;
-		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
-		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
-		assert(output[0] < 64);
-		assert(output[1] < 64);
-		assert(output[2] < 64);
-
-		if (datalength + 4 > targsize) {
-			return (-2);
-		}
-		target[datalength++] = Base64[output[0]];
-		target[datalength++] = Base64[output[1]];
-		if (srclength == 1) {
-			target[datalength++] = Pad64;
-		} else {
-			target[datalength++] = Base64[output[2]];
-		}
-		target[datalength++] = Pad64;
-	}
-	if (datalength >= targsize) {
-		return (-3);
-	}
-	target[datalength] = '\0';	/* Returned value doesn't count \0. */
-	return (int) (datalength);
-}
diff --git a/src/ldns/compat/b64_pton.c b/src/ldns/compat/b64_pton.c
deleted file mode 100644
index 18d8c8e..0000000
--- a/src/ldns/compat/b64_pton.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (c) 1996, 1998 by Internet Software Consortium.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/*
- * Portions Copyright (c) 1995 by International Business Machines, Inc.
- *
- * International Business Machines, Inc. (hereinafter called IBM) grants
- * permission under its copyrights to use, copy, modify, and distribute this
- * Software with or without fee, provided that the above copyright notice and
- * all paragraphs of this notice appear in all copies, and that the name of IBM
- * not be used in connection with the marketing of any product incorporating
- * the Software or modifications thereof, without specific, written prior
- * permission.
- *
- * To the extent it has a right to do so, IBM grants an immunity from suit
- * under its patents, if any, for the use, sale or manufacture of products to
- * the extent that such products are used for performing Domain Name System
- * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
- * granted for any product per se or for any other function of any product.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
- * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
- * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- */
-#include <ldns/config.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-static const char Base64[] =
-	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static const char Pad64 = '=';
-
-/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
-   The following encoding technique is taken from RFC 1521 by Borenstein
-   and Freed.  It is reproduced here in a slightly edited form for
-   convenience.
-
-   A 65-character subset of US-ASCII is used, enabling 6 bits to be
-   represented per printable character. (The extra 65th character, "=",
-   is used to signify a special processing function.)
-
-   The encoding process represents 24-bit groups of input bits as output
-   strings of 4 encoded characters. Proceeding from left to right, a
-   24-bit input group is formed by concatenating 3 8-bit input groups.
-   These 24 bits are then treated as 4 concatenated 6-bit groups, each
-   of which is translated into a single digit in the base64 alphabet.
-
-   Each 6-bit group is used as an index into an array of 64 printable
-   characters. The character referenced by the index is placed in the
-   output string.
-
-                         Table 1: The Base64 Alphabet
-
-      Value Encoding  Value Encoding  Value Encoding  Value Encoding
-          0 A            17 R            34 i            51 z
-          1 B            18 S            35 j            52 0
-          2 C            19 T            36 k            53 1
-          3 D            20 U            37 l            54 2
-          4 E            21 V            38 m            55 3
-          5 F            22 W            39 n            56 4
-          6 G            23 X            40 o            57 5
-          7 H            24 Y            41 p            58 6
-          8 I            25 Z            42 q            59 7
-          9 J            26 a            43 r            60 8
-         10 K            27 b            44 s            61 9
-         11 L            28 c            45 t            62 +
-         12 M            29 d            46 u            63 /
-         13 N            30 e            47 v
-         14 O            31 f            48 w         (pad) =
-         15 P            32 g            49 x
-         16 Q            33 h            50 y
-
-   Special processing is performed if fewer than 24 bits are available
-   at the end of the data being encoded.  A full encoding quantum is
-   always completed at the end of a quantity.  When fewer than 24 input
-   bits are available in an input group, zero bits are added (on the
-   right) to form an integral number of 6-bit groups.  Padding at the
-   end of the data is performed using the '=' character.
-
-   Since all base64 input is an integral number of octets, only the
-         -------------------------------------------------                       
-   following cases can arise:
-   
-       (1) the final quantum of encoding input is an integral
-           multiple of 24 bits; here, the final unit of encoded
-	   output will be an integral multiple of 4 characters
-	   with no "=" padding,
-       (2) the final quantum of encoding input is exactly 8 bits;
-           here, the final unit of encoded output will be two
-	   characters followed by two "=" padding characters, or
-       (3) the final quantum of encoding input is exactly 16 bits;
-           here, the final unit of encoded output will be three
-	   characters followed by one "=" padding character.
-   */
-
-/* skips all whitespace anywhere.
-   converts characters, four at a time, starting at (or after)
-   src from base - 64 numbers into three 8 bit bytes in the target area.
-   it returns the number of data bytes stored at the target, or -1 on error.
- */
-
-int
-ldns_b64_pton(char const *origsrc, uint8_t *target, size_t targsize)
-{
-	unsigned char const* src = (unsigned char*)origsrc;
-	int tarindex, state, ch;
-	char *pos;
-
-	state = 0;
-	tarindex = 0;
-
-	if (strlen(origsrc) == 0) {
-		return 0;
-	}
-
-	while ((ch = *src++) != '\0') {
-		if (isspace((unsigned char)ch))        /* Skip whitespace anywhere. */
-			continue;
-
-		if (ch == Pad64)
-			break;
-
-		pos = strchr(Base64, ch);
-		if (pos == 0) {
-			/* A non-base64 character. */
-			return (-1);
-		}
-
-		switch (state) {
-		case 0:
-			if (target) {
-				if ((size_t)tarindex >= targsize)
-					return (-1);
-				target[tarindex] = (pos - Base64) << 2;
-			}
-			state = 1;
-			break;
-		case 1:
-			if (target) {
-				if ((size_t)tarindex + 1 >= targsize)
-					return (-1);
-				target[tarindex]   |=  (pos - Base64) >> 4;
-				target[tarindex+1]  = ((pos - Base64) & 0x0f)
-							<< 4 ;
-			}
-			tarindex++;
-			state = 2;
-			break;
-		case 2:
-			if (target) {
-				if ((size_t)tarindex + 1 >= targsize)
-					return (-1);
-				target[tarindex]   |=  (pos - Base64) >> 2;
-				target[tarindex+1]  = ((pos - Base64) & 0x03)
-							<< 6;
-			}
-			tarindex++;
-			state = 3;
-			break;
-		case 3:
-			if (target) {
-				if ((size_t)tarindex >= targsize)
-					return (-1);
-				target[tarindex] |= (pos - Base64);
-			}
-			tarindex++;
-			state = 0;
-			break;
-		default:
-			abort();
-		}
-	}
-
-	/*
-	 * We are done decoding Base-64 chars.  Let's see if we ended
-	 * on a byte boundary, and/or with erroneous trailing characters.
-	 */
-
-	if (ch == Pad64) {		/* We got a pad char. */
-		ch = *src++;		/* Skip it, get next. */
-		switch (state) {
-		case 0:		/* Invalid = in first position */
-		case 1:		/* Invalid = in second position */
-			return (-1);
-
-		case 2:		/* Valid, means one byte of info */
-			/* Skip any number of spaces. */
-			for ((void)NULL; ch != '\0'; ch = *src++)
-				if (!isspace((unsigned char)ch))
-					break;
-			/* Make sure there is another trailing = sign. */
-			if (ch != Pad64)
-				return (-1);
-			ch = *src++;		/* Skip the = */
-			/* Fall through to "single trailing =" case. */
-			/* FALLTHROUGH */
-
-		case 3:		/* Valid, means two bytes of info */
-			/*
-			 * We know this char is an =.  Is there anything but
-			 * whitespace after it?
-			 */
-			for ((void)NULL; ch != '\0'; ch = *src++)
-				if (!isspace((unsigned char)ch))
-					return (-1);
-
-			/*
-			 * Now make sure for cases 2 and 3 that the "extra"
-			 * bits that slopped past the last full byte were
-			 * zeros.  If we don't check them, they become a
-			 * subliminal channel.
-			 */
-			if (target && target[tarindex] != 0)
-				return (-1);
-		}
-	} else {
-		/*
-		 * We ended by seeing the end of the string.  Make sure we
-		 * have no partial bytes lying around.
-		 */
-		if (state != 0)
-			return (-1);
-	}
-
-	return (tarindex);
-}
diff --git a/src/ldns/compat/strlcpy.c b/src/ldns/compat/strlcpy.c
deleted file mode 100644
index d6c34c1..0000000
--- a/src/ldns/compat/strlcpy.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* from openssh 4.3p2 compat/strlcpy.c */
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
-
-#include <ldns/config.h>
-#ifndef HAVE_STRLCPY
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Copy src to string dst of size siz.  At most siz-1 characters
- * will be copied.  Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t
-strlcpy(char *dst, const char *src, size_t siz)
-{
-	char *d = dst;
-	const char *s = src;
-	size_t n = siz;
-
-	/* Copy as many bytes as will fit */
-	if (n != 0 && --n != 0) {
-		do {
-			if ((*d++ = *s++) == 0)
-				break;
-		} while (--n != 0);
-	}
-
-	/* Not enough room in dst, add NUL and traverse rest of src */
-	if (n == 0) {
-		if (siz != 0)
-			*d = '\0';		/* NUL-terminate dst */
-		while (*s++)
-			;
-	}
-
-	return(s - src - 1);	/* count does not include NUL */
-}
-
-#endif /* !HAVE_STRLCPY */
diff --git a/src/ldns/dane.c b/src/ldns/dane.c
deleted file mode 100644
index 675dfa8..0000000
--- a/src/ldns/dane.c
+++ /dev/null
@@ -1,748 +0,0 @@
-/*
- * Verify or create TLS authentication with DANE (RFC6698)
- *
- * (c) NLnetLabs 2012
- *
- * See the file LICENSE for the license.
- *
- */
-
-#include <ldns/config.h>
-#ifdef USE_DANE
-
-#include <ldns/ldns.h>
-#include <ldns/dane.h>
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#ifdef HAVE_SSL
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/x509v3.h>
-#endif
-
-ldns_status
-ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner, const ldns_rdf* name,
-		uint16_t port, ldns_dane_transport transport)
-{
-	char buf[LDNS_MAX_DOMAINLEN];
-	size_t s;
-
-	assert(tlsa_owner != NULL);
-	assert(name != NULL);
-	assert(ldns_rdf_get_type(name) == LDNS_RDF_TYPE_DNAME);
-
-	s = (size_t)snprintf(buf, LDNS_MAX_DOMAINLEN, "X_%d", (int)port);
-	buf[0] = (char)(s - 1);
-
-	switch(transport) {
-	case LDNS_DANE_TRANSPORT_TCP:
-		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_tcp");
-		break;
-	
-	case LDNS_DANE_TRANSPORT_UDP:
-		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\004_udp");
-		break;
-
-	case LDNS_DANE_TRANSPORT_SCTP:
-		s += snprintf(buf + s, LDNS_MAX_DOMAINLEN - s, "\005_sctp");
-		break;
-	
-	default:
-		return LDNS_STATUS_DANE_UNKNOWN_TRANSPORT;
-	}
-	if (s + ldns_rdf_size(name) > LDNS_MAX_DOMAINLEN) {
-		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
-	}
-	memcpy(buf + s, ldns_rdf_data(name), ldns_rdf_size(name));
-	*tlsa_owner = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
-			s + ldns_rdf_size(name), buf);
-	if (*tlsa_owner == NULL) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
-
-
-#ifdef HAVE_SSL
-ldns_status
-ldns_dane_cert2rdf(ldns_rdf** rdf, X509* cert,
-		ldns_tlsa_selector      selector,
-		ldns_tlsa_matching_type matching_type)
-{
-	unsigned char* buf = NULL;
-	size_t len;
-
-	X509_PUBKEY* xpubkey;
-	EVP_PKEY* epubkey;
-
-	unsigned char* digest;
-
-	assert(rdf != NULL);
-	assert(cert != NULL);
-
-	switch(selector) {
-	case LDNS_TLSA_SELECTOR_FULL_CERTIFICATE:
-
-		len = (size_t)i2d_X509(cert, &buf);
-		break;
-
-	case LDNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO:
-
-#ifndef S_SPLINT_S
-		xpubkey = X509_get_X509_PUBKEY(cert);
-#endif
-		if (! xpubkey) {
-			return LDNS_STATUS_SSL_ERR;
-		}
-		epubkey = X509_PUBKEY_get(xpubkey);
-		if (! epubkey) {
-			return LDNS_STATUS_SSL_ERR;
-		}
-		len = (size_t)i2d_PUBKEY(epubkey, &buf);
-		break;
-	
-	default:
-		return LDNS_STATUS_DANE_UNKNOWN_SELECTOR;
-	}
-
-	switch(matching_type) {
-	case LDNS_TLSA_MATCHING_TYPE_NO_HASH_USED:
-
-		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, len, buf);
-		
-		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
-		break;
-	
-	case LDNS_TLSA_MATCHING_TYPE_SHA256:
-
-		digest = LDNS_XMALLOC(unsigned char, LDNS_SHA256_DIGEST_LENGTH);
-		if (digest == NULL) {
-			LDNS_FREE(buf);
-			return LDNS_STATUS_MEM_ERR;
-		}
-		(void) ldns_sha256(buf, (unsigned int)len, digest);
-		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, LDNS_SHA256_DIGEST_LENGTH,
-				digest);
-		LDNS_FREE(buf);
-
-		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
-		break;
-
-	case LDNS_TLSA_MATCHING_TYPE_SHA512:
-
-		digest = LDNS_XMALLOC(unsigned char, LDNS_SHA512_DIGEST_LENGTH);
-		if (digest == NULL) {
-			LDNS_FREE(buf);
-			return LDNS_STATUS_MEM_ERR;
-		}
-		(void) ldns_sha512(buf, (unsigned int)len, digest);
-		*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, LDNS_SHA512_DIGEST_LENGTH,
-				digest);
-		LDNS_FREE(buf);
-
-		return *rdf ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
-		break;
-	
-	default:
-		LDNS_FREE(buf);
-		return LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE;
-	}
-}
-
-
-/* Ordinary PKIX validation of cert (with extra_certs to help)
- * against the CA's in store
- */
-static ldns_status
-ldns_dane_pkix_validate(X509* cert, STACK_OF(X509)* extra_certs,
-		X509_STORE* store)
-{
-	X509_STORE_CTX* vrfy_ctx;
-	ldns_status s;
-
-	if (! store) {
-		return LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
-	}
-	vrfy_ctx = X509_STORE_CTX_new();
-	if (! vrfy_ctx) {
-
-		return LDNS_STATUS_SSL_ERR;
-
-	} else if (X509_STORE_CTX_init(vrfy_ctx, store,
-				cert, extra_certs) != 1) {
-		s = LDNS_STATUS_SSL_ERR;
-
-	} else if (X509_verify_cert(vrfy_ctx) == 1) {
-
-		s = LDNS_STATUS_OK;
-
-	} else {
-		s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
-	}
-	X509_STORE_CTX_free(vrfy_ctx);
-	return s;
-}
-
-
-/* Orinary PKIX validation of cert (with extra_certs to help)
- * against the CA's in store, but also return the validation chain.
- */
-static ldns_status
-ldns_dane_pkix_validate_and_get_chain(STACK_OF(X509)** chain, X509* cert,
-		STACK_OF(X509)* extra_certs, X509_STORE* store)
-{
-	ldns_status s;
-	X509_STORE* empty_store = NULL;
-	X509_STORE_CTX* vrfy_ctx;
-
-	assert(chain != NULL);
-
-	if (! store) {
-		store = empty_store = X509_STORE_new();
-	}
-	s = LDNS_STATUS_SSL_ERR;
-	vrfy_ctx = X509_STORE_CTX_new();
-	if (! vrfy_ctx) {
-
-		goto exit_free_empty_store;
-
-	} else if (X509_STORE_CTX_init(vrfy_ctx, store,
-					cert, extra_certs) != 1) {
-		goto exit_free_vrfy_ctx;
-
-	} else if (X509_verify_cert(vrfy_ctx) == 1) {
-
-		s = LDNS_STATUS_OK;
-
-	} else {
-		s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
-	}
-	*chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
-	if (! *chain) {
-		s = LDNS_STATUS_SSL_ERR;
-	}
-
-exit_free_vrfy_ctx:
-	X509_STORE_CTX_free(vrfy_ctx);
-
-exit_free_empty_store:
-	if (empty_store) {
-		X509_STORE_free(empty_store);
-	}
-	return s;
-}
-
-
-/* Return the validation chain that can be build out of cert, with extra_certs.
- */
-static ldns_status
-ldns_dane_pkix_get_chain(STACK_OF(X509)** chain,
-		X509* cert, STACK_OF(X509)* extra_certs)
-{
-	ldns_status s;
-	X509_STORE* empty_store = NULL;
-	X509_STORE_CTX* vrfy_ctx;
-
-	assert(chain != NULL);
-
-	empty_store = X509_STORE_new();
-	s = LDNS_STATUS_SSL_ERR;
-	vrfy_ctx = X509_STORE_CTX_new();
-	if (! vrfy_ctx) {
-
-		goto exit_free_empty_store;
-
-	} else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
-					cert, extra_certs) != 1) {
-		goto exit_free_vrfy_ctx;
-	}
-	(void) X509_verify_cert(vrfy_ctx);
-	*chain = X509_STORE_CTX_get1_chain(vrfy_ctx);
-	if (! *chain) {
-		s = LDNS_STATUS_SSL_ERR;
-	} else {
-		s = LDNS_STATUS_OK;
-	}
-exit_free_vrfy_ctx:
-	X509_STORE_CTX_free(vrfy_ctx);
-
-exit_free_empty_store:
-	X509_STORE_free(empty_store);
-	return s;
-}
-
-
-/* Pop n+1 certs and return the last popped.
- */
-static ldns_status
-ldns_dane_get_nth_cert_from_validation_chain(
-		X509** cert, STACK_OF(X509)* chain, int n, bool ca)
-{
-	if (n >= sk_X509_num(chain) || n < 0) {
-		return LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE;
-	}
-	*cert = sk_X509_pop(chain);
-	while (n-- > 0) {
-		X509_free(*cert);
-		*cert = sk_X509_pop(chain);
-	}
-	if (ca && ! X509_check_ca(*cert)) {
-		return LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
-	}
-	return LDNS_STATUS_OK;
-}
-
-
-/* Create validation chain with cert and extra_certs and returns the last
- * self-signed (if present).
- */
-static ldns_status
-ldns_dane_pkix_get_last_self_signed(X509** out_cert,
-		X509* cert, STACK_OF(X509)* extra_certs)
-{
-	ldns_status s;
-	X509_STORE* empty_store = NULL;
-	X509_STORE_CTX* vrfy_ctx;
-
-	assert(out_cert != NULL);
-
-	empty_store = X509_STORE_new();
-	s = LDNS_STATUS_SSL_ERR;
-	vrfy_ctx = X509_STORE_CTX_new();
-	if (! vrfy_ctx) {
-		goto exit_free_empty_store;
-
-	} else if (X509_STORE_CTX_init(vrfy_ctx, empty_store,
-					cert, extra_certs) != 1) {
-		goto exit_free_vrfy_ctx;
-
-	}
-	(void) X509_verify_cert(vrfy_ctx);
-	if (vrfy_ctx->error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
-	    vrfy_ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT){
-
-		*out_cert = X509_STORE_CTX_get_current_cert( vrfy_ctx);
-		s = LDNS_STATUS_OK;
-	} else {
-		s = LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR;
-	}
-exit_free_vrfy_ctx:
-	X509_STORE_CTX_free(vrfy_ctx);
-
-exit_free_empty_store:
-	X509_STORE_free(empty_store);
-	return s;
-}
-
-
-ldns_status
-ldns_dane_select_certificate(X509** selected_cert,
-		X509* cert, STACK_OF(X509)* extra_certs,
-		X509_STORE* pkix_validation_store,
-		ldns_tlsa_certificate_usage cert_usage, int offset)
-{
-	ldns_status s;
-	STACK_OF(X509)* pkix_validation_chain = NULL;
-
-	assert(selected_cert != NULL);
-	assert(cert != NULL);
-
-	/* With PKIX validation explicitely turned off (pkix_validation_store
-	 *  == NULL), treat the "CA constraint" and "Service certificate
-	 * constraint" the same as "Trust anchor assertion" and "Domain issued
-	 * certificate" respectively.
-	 */
-	if (pkix_validation_store == NULL) {
-		switch (cert_usage) {
-
-		case LDNS_TLSA_USAGE_CA_CONSTRAINT:
-
-			cert_usage = LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION;
-			break;
-
-		case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
-
-			cert_usage = LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE;
-			break;
-
-		default:
-			break;
-		}
-	}
-
-	/* Now what to do with each Certificate usage...
-	 */
-	switch (cert_usage) {
-
-	case LDNS_TLSA_USAGE_CA_CONSTRAINT:
-
-		s = ldns_dane_pkix_validate_and_get_chain(
-				&pkix_validation_chain,
-				cert, extra_certs,
-				pkix_validation_store);
-		if (! pkix_validation_chain) {
-			return s;
-		}
-		if (s == LDNS_STATUS_OK) {
-			if (offset == -1) {
-				offset = 0;
-			}
-			s = ldns_dane_get_nth_cert_from_validation_chain(
-					selected_cert, pkix_validation_chain,
-					offset, true);
-		}
-		sk_X509_pop_free(pkix_validation_chain, X509_free);
-		return s;
-		break;
-
-
-	case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
-
-		*selected_cert = cert;
-		return ldns_dane_pkix_validate(cert, extra_certs,
-				pkix_validation_store);
-		break;
-
-
-	case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
-
-		if (offset == -1) {
-			s = ldns_dane_pkix_get_last_self_signed(
-					selected_cert, cert, extra_certs);
-			return s;
-		} else {
-			s = ldns_dane_pkix_get_chain(
-					&pkix_validation_chain,
-					cert, extra_certs);
-			if (s == LDNS_STATUS_OK) {
-				s =
-				ldns_dane_get_nth_cert_from_validation_chain(
-					selected_cert, pkix_validation_chain,
-					offset, false);
-			} else if (! pkix_validation_chain) {
-				return s;
-			}
-			sk_X509_pop_free(pkix_validation_chain, X509_free);
-			return s;
-		}
-		break;
-
-
-	case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
-
-		*selected_cert = cert;
-		return LDNS_STATUS_OK;
-		break;
-	
-	default:
-		return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
-		break;
-	}
-}
-
-
-ldns_status
-ldns_dane_create_tlsa_rr(ldns_rr** tlsa,
-		ldns_tlsa_certificate_usage certificate_usage,
-		ldns_tlsa_selector          selector,
-		ldns_tlsa_matching_type     matching_type,
-		X509* cert)
-{
-	ldns_rdf* rdf;
-	ldns_status s;
-
-	assert(tlsa != NULL);
-	assert(cert != NULL);
-
-	/* create rr */
-	*tlsa = ldns_rr_new_frm_type(LDNS_RR_TYPE_TLSA);
-	if (*tlsa == NULL) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
-			(uint8_t)certificate_usage);
-	if (rdf == NULL) {
-		goto memerror;
-	}
-	(void) ldns_rr_set_rdf(*tlsa, rdf, 0);
-
-	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)selector);
-	if (rdf == NULL) {
-		goto memerror;
-	}
-	(void) ldns_rr_set_rdf(*tlsa, rdf, 1);
-
-	rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t)matching_type);
-	if (rdf == NULL) {
-		goto memerror;
-	}
-	(void) ldns_rr_set_rdf(*tlsa, rdf, 2);
-
-	s = ldns_dane_cert2rdf(&rdf, cert, selector, matching_type);
-	if (s == LDNS_STATUS_OK) {
-		(void) ldns_rr_set_rdf(*tlsa, rdf, 3);
-		return LDNS_STATUS_OK;
-	}
-	ldns_rr_free(*tlsa);
-	*tlsa = NULL;
-	return s;
-
-memerror:
-	ldns_rr_free(*tlsa);
-	*tlsa = NULL;
-	return LDNS_STATUS_MEM_ERR;
-}
-
-
-/* Return tlsas that actually are TLSA resource records with known values
- * for the Certificate usage, Selector and Matching type rdata fields.
- */
-static ldns_rr_list*
-ldns_dane_filter_unusable_records(const ldns_rr_list* tlsas)
-{
-	size_t i;
-	ldns_rr_list* r = ldns_rr_list_new();
-	ldns_rr* tlsa_rr;
-
-	if (! r) {
-		return NULL;
-	}
-	for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
-		tlsa_rr = ldns_rr_list_rr(tlsas, i);
-		if (ldns_rr_get_type(tlsa_rr) == LDNS_RR_TYPE_TLSA &&
-		    ldns_rr_rd_count(tlsa_rr) == 4 &&
-		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0)) <= 3 &&
-		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1)) <= 1 &&
-		    ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2)) <= 2) {
-
-			if (! ldns_rr_list_push_rr(r, tlsa_rr)) {
-				ldns_rr_list_free(r);
-				return NULL;
-			}
-		}
-	}
-	return r;
-}
-
-
-/* Return whether cert/selector/matching_type matches data.
- */
-static ldns_status
-ldns_dane_match_cert_with_data(X509* cert, ldns_tlsa_selector selector,
-		ldns_tlsa_matching_type matching_type, ldns_rdf* data)
-{
-	ldns_status s;
-	ldns_rdf* match_data;
-
-	s = ldns_dane_cert2rdf(&match_data, cert, selector, matching_type);
-	if (s == LDNS_STATUS_OK) {
-		if (ldns_rdf_compare(data, match_data) != 0) {
-			s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
-		}
-		ldns_rdf_free(match_data);
-	}
-	return s;
-}
-
-
-/* Return whether any certificate from the chain with selector/matching_type
- * matches data.
- * ca should be true if the certificate has to be a CA certificate too.
- */
-static ldns_status
-ldns_dane_match_any_cert_with_data(STACK_OF(X509)* chain,
-		ldns_tlsa_selector      selector,
-		ldns_tlsa_matching_type matching_type,
-		ldns_rdf* data, bool ca)
-{
-	ldns_status s = LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH;
-	size_t n, i;
-	X509* cert;
-
-	n = (size_t)sk_X509_num(chain);
-	for (i = 0; i < n; i++) {
-		cert = sk_X509_pop(chain);
-		if (! cert) {
-			s = LDNS_STATUS_SSL_ERR;
-			break;
-		}
-		s = ldns_dane_match_cert_with_data(cert,
-				selector, matching_type, data);
-		if (ca && s == LDNS_STATUS_OK && ! X509_check_ca(cert)) {
-			s = LDNS_STATUS_DANE_NON_CA_CERTIFICATE;
-		}
-		X509_free(cert);
-		if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH) {
-			break;
-		}
-		/* when s == LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
-		 * try to match the next certificate
-		 */
-	}
-	return s;
-}
-
-
-ldns_status
-ldns_dane_verify_rr(const ldns_rr* tlsa_rr,
-		X509* cert, STACK_OF(X509)* extra_certs,
-		X509_STORE* pkix_validation_store)
-{
-	ldns_status s;
-
-	STACK_OF(X509)* pkix_validation_chain = NULL;
-
-	ldns_tlsa_certificate_usage cert_usage;
-	ldns_tlsa_selector          selector;
-	ldns_tlsa_matching_type     matching_type;
-	ldns_rdf*                   data;
-
-	if (! tlsa_rr) {
-		/* No TLSA, so regular PKIX validation
-		 */
-		return ldns_dane_pkix_validate(cert, extra_certs,
-				pkix_validation_store);
-	}
-	cert_usage    = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 0));
-	selector      = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 1));
-	matching_type = ldns_rdf2native_int8(ldns_rr_rdf(tlsa_rr, 2));
-	data          =                      ldns_rr_rdf(tlsa_rr, 3) ;
-
-	switch (cert_usage) {
-	case LDNS_TLSA_USAGE_CA_CONSTRAINT:
-		s = ldns_dane_pkix_validate_and_get_chain(
-				&pkix_validation_chain, 
-				cert, extra_certs,
-				pkix_validation_store);
-		if (! pkix_validation_chain) {
-			return s;
-		}
-		if (s == LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
-			/*
-			 * NO PKIX validation. We still try to match *any*
-			 * certificate from the chain, so we return
-			 * TLSA errors over PKIX errors.
-			 *
-			 * i.e. When the TLSA matches no certificate, we return
-			 * TLSA_DID_NOT_MATCH and not PKIX_DID_NOT_VALIDATE
-			 */
-			s = ldns_dane_match_any_cert_with_data(
-					pkix_validation_chain,
-					selector, matching_type, data, true);
-
-			if (s == LDNS_STATUS_OK) {
-				/* A TLSA record did match a cert from the
-				 * chain, thus the error is failed PKIX
-				 * validation.
-				 */
-				s = LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE;
-			}
-
-		} else if (s == LDNS_STATUS_OK) { 
-			/* PKIX validated, does the TLSA match too? */
-
-			s = ldns_dane_match_any_cert_with_data(
-					pkix_validation_chain,
-					selector, matching_type, data, true);
-		}
-		sk_X509_pop_free(pkix_validation_chain, X509_free);
-		return s;
-		break;
-
-	case LDNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT:
-		s = ldns_dane_match_cert_with_data(cert,
-				selector, matching_type, data);
-
-		if (s == LDNS_STATUS_OK) {
-			return ldns_dane_pkix_validate(cert, extra_certs,
-					pkix_validation_store);
-		}
-		return s;
-		break;
-
-	case LDNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION:
-		s = ldns_dane_pkix_get_chain(&pkix_validation_chain,
-				cert, extra_certs);
-
-		if (s == LDNS_STATUS_OK) {
-			s = ldns_dane_match_any_cert_with_data(
-					pkix_validation_chain,
-					selector, matching_type, data, false);
-
-		} else if (! pkix_validation_chain) {
-			return s;
-		}
-		sk_X509_pop_free(pkix_validation_chain, X509_free);
-		return s;
-		break;
-
-	case LDNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE:
-		return ldns_dane_match_cert_with_data(cert,
-				selector, matching_type, data);
-		break;
-
-	default:
-		break;
-	}
-	return LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE;
-}
-
-
-ldns_status
-ldns_dane_verify(ldns_rr_list* tlsas,
-		X509* cert, STACK_OF(X509)* extra_certs,
-		X509_STORE* pkix_validation_store)
-{
-	size_t i;
-	ldns_rr* tlsa_rr;
-	ldns_status s = LDNS_STATUS_OK, ps;
-
-	assert(cert != NULL);
-
-	if (tlsas && ldns_rr_list_rr_count(tlsas) > 0) {
-		tlsas = ldns_dane_filter_unusable_records(tlsas);
-		if (! tlsas) {
-			return LDNS_STATUS_MEM_ERR;
-		}
-	}
-	if (! tlsas || ldns_rr_list_rr_count(tlsas) == 0) {
-		/* No TLSA's, so regular PKIX validation
-		 */
-		return ldns_dane_pkix_validate(cert, extra_certs,
-				pkix_validation_store);
-	} else {
-		for (i = 0; i < ldns_rr_list_rr_count(tlsas); i++) {
-			tlsa_rr = ldns_rr_list_rr(tlsas, i);
-			ps = s;
-			s = ldns_dane_verify_rr(tlsa_rr, cert, extra_certs,
-					pkix_validation_store);
-
-			if (s != LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH &&
-			    s != LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE) {
-
-				/* which would be LDNS_STATUS_OK (match)
-				 * or some fatal error preventing use from
-				 * trying the next TLSA record.
-				 */
-				break;
-			}
-			s = (s > ps ? s : ps); /* prefer PKIX_DID_NOT_VALIDATE
-						* over   TLSA_DID_NOT_MATCH
-						*/
-		}
-		ldns_rr_list_free(tlsas);
-	}
-	return s;
-}
-#endif /* HAVE_SSL */
-#endif /* USE_DANE */
diff --git a/src/ldns/dname.c b/src/ldns/dname.c
deleted file mode 100644
index 55aba5d..0000000
--- a/src/ldns/dname.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * dname.c
- *
- * dname specific rdata implementations
- * A dname is a rdf structure with type LDNS_RDF_TYPE_DNAME
- * It is not a /real/ type! All function must therefor check
- * for LDNS_RDF_TYPE_DNAME.
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-/* Returns whether the last label in the name is a root label (a empty label).
- * Note that it is not enough to just test the last character to be 0,
- * because it may be part of the last label itself.
- */
-static bool
-ldns_dname_last_label_is_root_label(const ldns_rdf* dname)
-{
-	size_t src_pos;
-	size_t len = 0;
-
-	for (src_pos = 0; src_pos < ldns_rdf_size(dname); src_pos += len + 1) {
-		len = ldns_rdf_data(dname)[src_pos];
-	}
-	assert(src_pos == ldns_rdf_size(dname));
-
-	return src_pos > 0 && len == 0;
-}
-
-ldns_rdf *
-ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
-{
-	ldns_rdf *new;
-	uint16_t new_size;
-	uint8_t *buf;
-	uint16_t left_size;
-
-	if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
-			ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
-		return NULL;
-	}
-
-	/* remove root label if it is present at the end of the left
-	 * rd, by reducing the size with 1
-	 */
-	left_size = ldns_rdf_size(rd1);
-	if (ldns_dname_last_label_is_root_label(rd1)) {
-		left_size--;
-	}
-
-	/* we overwrite the nullbyte of rd1 */
-	new_size = left_size + ldns_rdf_size(rd2);
-	buf = LDNS_XMALLOC(uint8_t, new_size);
-	if (!buf) {
-		return NULL;
-	}
-
-	/* put the two dname's after each other */
-	memcpy(buf, ldns_rdf_data(rd1), left_size);
-	memcpy(buf + left_size, ldns_rdf_data(rd2), ldns_rdf_size(rd2));
-
-	new = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, new_size, buf);
-
-	LDNS_FREE(buf);
-	return new;
-}
-
-ldns_status
-ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
-{
-	uint16_t left_size;
-	uint16_t size;
-	uint8_t* newd;
-
-	if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
-			ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* remove root label if it is present at the end of the left
-	 * rd, by reducing the size with 1
-	 */
-	left_size = ldns_rdf_size(rd1);
-	if (ldns_dname_last_label_is_root_label(rd1)) {
-		left_size--;
-	}
-
-	size = left_size + ldns_rdf_size(rd2);
-	newd = LDNS_XREALLOC(ldns_rdf_data(rd1), uint8_t, size);
-	if(!newd) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	ldns_rdf_set_data(rd1, newd);
-	memcpy(ldns_rdf_data(rd1) + left_size, ldns_rdf_data(rd2),
-			ldns_rdf_size(rd2));
-	ldns_rdf_set_size(rd1, size);
-
-	return LDNS_STATUS_OK;
-}
-
-ldns_rdf*
-ldns_dname_reverse(const ldns_rdf *dname)
-{
-	size_t rd_size;
-	uint8_t* buf;
-	ldns_rdf* new;
-	size_t src_pos;
-	size_t len ;
-
-	assert(ldns_rdf_get_type(dname) == LDNS_RDF_TYPE_DNAME);
-	
-	rd_size = ldns_rdf_size(dname);
-	buf = LDNS_XMALLOC(uint8_t, rd_size);
-	if (! buf) {
-		return NULL;
-	}
-	new = ldns_rdf_new(LDNS_RDF_TYPE_DNAME, rd_size, buf);
-	if (! new) {
-		LDNS_FREE(buf);
-		return NULL;
-	}
-	
-	/* If dname ends in a root label, the reverse should too.
-	 */
-	if (ldns_dname_last_label_is_root_label(dname)) {
-		buf[rd_size - 1] = 0;
-		rd_size -= 1;
-	}
-	for (src_pos = 0; src_pos < rd_size; src_pos += len + 1) {
-		len = ldns_rdf_data(dname)[src_pos];
-		memcpy(&buf[rd_size - src_pos - len - 1],
-				&ldns_rdf_data(dname)[src_pos], len + 1);
-	}
-	return new;
-}
-
-ldns_rdf *
-ldns_dname_clone_from(const ldns_rdf *d, uint16_t n)
-{
-	uint8_t *data;
-	uint8_t label_size;
-	size_t data_size;
-
-	if (!d ||
-	    ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME ||
-	    ldns_dname_label_count(d) < n) {
-		return NULL;
-	}
-
-	data = ldns_rdf_data(d);
-	data_size = ldns_rdf_size(d);
-	while (n > 0) {
-		label_size = data[0] + 1;
-		data += label_size;
-		if (data_size < label_size) {
-			/* this label is very broken */
-			return NULL;
-		}
-		data_size -= label_size;
-		n--;
-	}
-
-	return ldns_dname_new_frm_data(data_size, data);
-}
-
-ldns_rdf *
-ldns_dname_left_chop(const ldns_rdf *d)
-{
-	uint8_t label_pos;
-	ldns_rdf *chop;
-
-	if (!d) {
-		return NULL;
-	}
-
-	if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
-		return NULL;
-	}
-	if (ldns_dname_label_count(d) == 0) {
-		/* root label */
-		return NULL;
-	}
-	/* 05blaat02nl00 */
-	label_pos = ldns_rdf_data(d)[0];
-
-	chop = ldns_dname_new_frm_data(ldns_rdf_size(d) - label_pos - 1,
-			ldns_rdf_data(d) + label_pos + 1);
-	return chop;
-}
-
-uint8_t
-ldns_dname_label_count(const ldns_rdf *r)
-{
-        uint16_t src_pos;
-        uint16_t len;
-        uint8_t i;
-        size_t r_size;
-
-	if (!r) {
-		return 0;
-	}
-
-	i = 0;
-	src_pos = 0;
-	r_size = ldns_rdf_size(r);
-
-	if (ldns_rdf_get_type(r) != LDNS_RDF_TYPE_DNAME) {
-		return 0;
-	} else {
-		len = ldns_rdf_data(r)[src_pos]; /* start of the label */
-
-		/* single root label */
-		if (1 == r_size) {
-			return 0;
-		} else {
-			while ((len > 0) && src_pos < r_size) {
-				src_pos++;
-				src_pos += len;
-				len = ldns_rdf_data(r)[src_pos];
-				i++;
-			}
-		}
-	}
-	return i;
-}
-
-ldns_rdf *
-ldns_dname_new(uint16_t s, void *d)
-{
-        ldns_rdf *rd;
-
-        rd = LDNS_MALLOC(ldns_rdf);
-        if (!rd) {
-                return NULL;
-        }
-        ldns_rdf_set_size(rd, s);
-        ldns_rdf_set_type(rd, LDNS_RDF_TYPE_DNAME);
-        ldns_rdf_set_data(rd, d);
-        return rd;
-}
-
-ldns_rdf *
-ldns_dname_new_frm_str(const char *str)
-{
-	return ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, str);
-}
-
-ldns_rdf *
-ldns_dname_new_frm_data(uint16_t size, const void *data)
-{
-	return ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, size, data);
-}
-
-void
-ldns_dname2canonical(const ldns_rdf *rd)
-{
-	uint8_t *rdd;
-	uint16_t i;
-
-	if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_DNAME) {
-		return;
-	}
-
-	rdd = (uint8_t*)ldns_rdf_data(rd);
-	for (i = 0; i < ldns_rdf_size(rd); i++, rdd++) {
-		*rdd = (uint8_t)LDNS_DNAME_NORMALIZE((int)*rdd);
-	}
-}
-
-bool
-ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
-{
-	uint8_t sub_lab;
-	uint8_t par_lab;
-	int8_t i, j;
-	ldns_rdf *tmp_sub = NULL;
-	ldns_rdf *tmp_par = NULL;
-    ldns_rdf *sub_clone;
-    ldns_rdf *parent_clone;
-    bool result = true;
-
-	if (ldns_rdf_get_type(sub) != LDNS_RDF_TYPE_DNAME ||
-			ldns_rdf_get_type(parent) != LDNS_RDF_TYPE_DNAME ||
-			ldns_rdf_compare(sub, parent) == 0) {
-		return false;
-	}
-
-    /* would be nicer if we do not have to clone... */
-    sub_clone = ldns_dname_clone_from(sub, 0);
-    parent_clone = ldns_dname_clone_from(parent, 0);
-    ldns_dname2canonical(sub_clone);
-    ldns_dname2canonical(parent_clone);
-
-	sub_lab = ldns_dname_label_count(sub_clone);
-	par_lab = ldns_dname_label_count(parent_clone);
-
-	/* if sub sits above parent, it cannot be a child/sub domain */
-	if (sub_lab < par_lab) {
-		result = false;
-	} else {
-		/* check all labels the from the parent labels, from right to left.
-		 * When they /all/ match we have found a subdomain
-		 */
-		j = sub_lab - 1; /* we count from zero, thank you */
-		for (i = par_lab -1; i >= 0; i--) {
-			tmp_sub = ldns_dname_label(sub_clone, j);
-			tmp_par = ldns_dname_label(parent_clone, i);
-			if (!tmp_sub || !tmp_par) {
-				/* deep free does null check */
-				ldns_rdf_deep_free(tmp_sub);
-				ldns_rdf_deep_free(tmp_par);
-				result = false;
-				break;
-			}
-
-			if (ldns_rdf_compare(tmp_sub, tmp_par) != 0) {
-				/* they are not equal */
-				ldns_rdf_deep_free(tmp_sub);
-				ldns_rdf_deep_free(tmp_par);
-				result = false;
-				break;
-			}
-			ldns_rdf_deep_free(tmp_sub);
-			ldns_rdf_deep_free(tmp_par);
-			j--;
-		}
-	}
-	ldns_rdf_deep_free(sub_clone);
-	ldns_rdf_deep_free(parent_clone);
-	return result;
-}
-
-int
-ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
-{
-	size_t lc1, lc2, lc1f, lc2f;
-	size_t i;
-	int result = 0;
-	uint8_t *lp1, *lp2;
-
-	/* see RFC4034 for this algorithm */
-	/* this algorithm assumes the names are normalized to case */
-
-        /* only when both are not NULL we can say anything about them */
-        if (!dname1 && !dname2) {
-                return 0;
-        }
-        if (!dname1 || !dname2) {
-                return -1;
-        }
-	/* asserts must happen later as we are looking in the
-	 * dname, which could be NULL. But this case is handled
-	 * above
-	 */
-	assert(ldns_rdf_get_type(dname1) == LDNS_RDF_TYPE_DNAME);
-	assert(ldns_rdf_get_type(dname2) == LDNS_RDF_TYPE_DNAME);
-
-	lc1 = ldns_dname_label_count(dname1);
-	lc2 = ldns_dname_label_count(dname2);
-
-	if (lc1 == 0 && lc2 == 0) {
-		return 0;
-	}
-	if (lc1 == 0) {
-		return -1;
-	}
-	if (lc2 == 0) {
-		return 1;
-	}
-	lc1--;
-	lc2--;
-	/* we start at the last label */
-	while (true) {
-		/* find the label first */
-		lc1f = lc1;
-		lp1 = ldns_rdf_data(dname1);
-		while (lc1f > 0) {
-			lp1 += *lp1 + 1;
-			lc1f--;
-		}
-
-		/* and find the other one */
-		lc2f = lc2;
-		lp2 = ldns_rdf_data(dname2);
-		while (lc2f > 0) {
-			lp2 += *lp2 + 1;
-			lc2f--;
-		}
-
-		/* now check the label character for character. */
-		for (i = 1; i < (size_t)(*lp1 + 1); i++) {
-			if (i > *lp2) {
-				/* apparently label 1 is larger */
-				result = 1;
-				goto done;
-			}
-			if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) <
-			    LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
-			    result = -1;
-			    goto done;
-			} else if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) >
-			    LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
-			    result = 1;
-			    goto done;
-			}
-		}
-		if (*lp1 < *lp2) {
-			/* apparently label 2 is larger */
-			result = -1;
-			goto done;
-		}
-		if (lc1 == 0 && lc2 > 0) {
-			result = -1;
-			goto done;
-		} else if (lc1 > 0 && lc2 == 0) {
-			result = 1;
-			goto done;
-		} else if (lc1 == 0 && lc2 == 0) {
-			result = 0;
-			goto done;
-		}
-		lc1--;
-		lc2--;
-	}
-
-	done:
-	return result;
-}
-
-int
-ldns_dname_is_wildcard(const ldns_rdf* dname)
-{
-	return ( ldns_dname_label_count(dname) > 0 &&
-		 ldns_rdf_data(dname)[0] == 1 &&
-		 ldns_rdf_data(dname)[1] == '*');
-}
-
-int
-ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard)
-{
-	ldns_rdf *wc_chopped;
-	int result;
-	/* check whether it really is a wildcard */
-	if (ldns_dname_is_wildcard(wildcard)) {
-		/* ok, so the dname needs to be a subdomain of the wildcard
-		 * without the *
-		 */
-		wc_chopped = ldns_dname_left_chop(wildcard);
-		result = (int) ldns_dname_is_subdomain(dname, wc_chopped);
-		ldns_rdf_deep_free(wc_chopped);
-	} else {
-		result = (ldns_dname_compare(dname, wildcard) == 0);
-	}
-	return result;
-}
-
-/* nsec test: does prev <= middle < next
- * -1 = yes
- * 0 = error/can't tell
- * 1 = no
- */
-int
-ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle,
-		const ldns_rdf *next)
-{
-	int prev_check, next_check;
-
-	assert(ldns_rdf_get_type(prev) == LDNS_RDF_TYPE_DNAME);
-	assert(ldns_rdf_get_type(middle) == LDNS_RDF_TYPE_DNAME);
-	assert(ldns_rdf_get_type(next) == LDNS_RDF_TYPE_DNAME);
-
-	prev_check = ldns_dname_compare(prev, middle);
-	next_check = ldns_dname_compare(middle, next);
-	/* <= next. This cannot be the case for nsec, because then we would
-	 * have gotten the nsec of next...
-	 */
-	if (next_check == 0) {
-		return 0;
-	}
-
-			/* <= */
-	if ((prev_check == -1 || prev_check == 0) &&
-			/* < */
-			next_check == -1) {
-		return -1;
-	} else {
-		return 1;
-	}
-}
-
-
-bool
-ldns_dname_str_absolute(const char *dname_str)
-{
-        const char* s;
-	if(dname_str && strcmp(dname_str, ".") == 0)
-		return 1;
-        if(!dname_str || strlen(dname_str) < 2)
-                return 0;
-        if(dname_str[strlen(dname_str) - 1] != '.')
-                return 0;
-        if(dname_str[strlen(dname_str) - 2] != '\\')
-                return 1; /* ends in . and no \ before it */
-        /* so we have the case of ends in . and there is \ before it */
-        for(s=dname_str; *s; s++) {
-                if(*s == '\\') {
-                        if(s[1] && s[2] && s[3] /* check length */
-                                && isdigit(s[1]) && isdigit(s[2]) && 
-                                isdigit(s[3]))
-                                s += 3;
-                        else if(!s[1] || isdigit(s[1])) /* escape of nul,0-9 */
-                                return 0; /* parse error */
-                        else s++; /* another character escaped */
-                }
-                else if(!*(s+1) && *s == '.')
-                        return 1; /* trailing dot, unescaped */
-        }
-        return 0;
-}
-
-bool
-ldns_dname_absolute(const ldns_rdf *rdf)
-{
-	char *str = ldns_rdf2str(rdf);
-	if (str) {
-		bool r = ldns_dname_str_absolute(str);
-		LDNS_FREE(str);
-		return r;
-	}
-	return false;
-}
-
-ldns_rdf *
-ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
-{
-	uint8_t labelcnt;
-	uint16_t src_pos;
-	uint16_t len;
-	ldns_rdf *tmpnew;
-	size_t s;
-	uint8_t *data;
-
-	if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_DNAME) {
-		return NULL;
-	}
-
-	labelcnt = 0;
-	src_pos = 0;
-	s = ldns_rdf_size(rdf);
-
-	len = ldns_rdf_data(rdf)[src_pos]; /* label start */
-	while ((len > 0) && src_pos < s) {
-		if (labelcnt == labelpos) {
-			/* found our label */
-			data = LDNS_XMALLOC(uint8_t, len + 2);
-			if (!data) {
-				return NULL;
-			}
-			memcpy(data, ldns_rdf_data(rdf) + src_pos, len + 1);
-			data[len + 2 - 1] = 0;
-
-			tmpnew = ldns_rdf_new( LDNS_RDF_TYPE_DNAME
-					     , len + 2, data);
-			if (!tmpnew) {
-				LDNS_FREE(data);
-				return NULL;
-			}
-			return tmpnew;
-		}
-		src_pos++;
-		src_pos += len;
-		len = ldns_rdf_data(rdf)[src_pos];
-		labelcnt++;
-	}
-	return NULL;
-}
diff --git a/src/ldns/dnssec.c b/src/ldns/dnssec.c
deleted file mode 100644
index a41a9f6..0000000
--- a/src/ldns/dnssec.c
+++ /dev/null
@@ -1,1869 +0,0 @@
-/*
- * dnssec.c
- *
- * contains the cryptographic function needed for DNSSEC in ldns
- * The crypto library used is openssl
- *
- * (c) NLnet Labs, 2004-2008
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-#include <ldns/dnssec.h>
-
-#include <strings.h>
-#include <time.h>
-
-#ifdef HAVE_SSL
-#include <openssl/ssl.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/md5.h>
-#endif
-
-ldns_rr *
-ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name,
-                                        const ldns_rr_type type,
-                                        const ldns_rr_list *rrs)
-{
-	size_t i;
-	ldns_rr *candidate;
-
-	if (!name || !rrs) {
-		return NULL;
-	}
-
-	for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
-		candidate = ldns_rr_list_rr(rrs, i);
-		if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_RRSIG) {
-			if (ldns_dname_compare(ldns_rr_owner(candidate),
-			                       name) == 0 &&
-			    ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(candidate))
-			    == type
-			    ) {
-				return candidate;
-			}
-		}
-	}
-
-	return NULL;
-}
-
-ldns_rr *
-ldns_dnssec_get_dnskey_for_rrsig(const ldns_rr *rrsig,
-						   const ldns_rr_list *rrs)
-{
-	size_t i;
-	ldns_rr *candidate;
-
-	if (!rrsig || !rrs) {
-		return NULL;
-	}
-
-	for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
-		candidate = ldns_rr_list_rr(rrs, i);
-		if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_DNSKEY) {
-			if (ldns_dname_compare(ldns_rr_owner(candidate),
-			                       ldns_rr_rrsig_signame(rrsig)) == 0 &&
-			    ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig)) ==
-			    ldns_calc_keytag(candidate)
-			    ) {
-				return candidate;
-			}
-		}
-	}
-
-	return NULL;
-}
-
-ldns_rdf *
-ldns_nsec_get_bitmap(ldns_rr *nsec) {
-	if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
-		return ldns_rr_rdf(nsec, 1);
-	} else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
-		return ldns_rr_rdf(nsec, 5);
-	} else {
-		return NULL;
-	}
-}
-
-/*return the owner name of the closest encloser for name from the list of rrs */
-/* this is NOT the hash, but the original name! */
-ldns_rdf *
-ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
-                                   ATTR_UNUSED(ldns_rr_type qtype),
-                                   ldns_rr_list *nsec3s)
-{
-	/* remember parameters, they must match */
-	uint8_t algorithm;
-	uint32_t iterations;
-	uint8_t salt_length;
-	uint8_t *salt;
-
-	ldns_rdf *sname, *hashed_sname, *tmp;
-	bool flag;
-
-	bool exact_match_found;
-	bool in_range_found;
-
-	ldns_status status;
-	ldns_rdf *zone_name;
-
-	size_t nsec_i;
-	ldns_rr *nsec;
-	ldns_rdf *result = NULL;
-
-	if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) {
-		return NULL;
-	}
-
-	nsec = ldns_rr_list_rr(nsec3s, 0);
-	algorithm = ldns_nsec3_algorithm(nsec);
-	salt_length = ldns_nsec3_salt_length(nsec);
-	salt = ldns_nsec3_salt_data(nsec);
-	iterations = ldns_nsec3_iterations(nsec);
-
-	sname = ldns_rdf_clone(qname);
-
-	flag = false;
-
-	zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec));
-
-	/* algorithm from nsec3-07 8.3 */
-	while (ldns_dname_label_count(sname) > 0) {
-		exact_match_found = false;
-		in_range_found = false;
-
-		hashed_sname = ldns_nsec3_hash_name(sname,
-									 algorithm,
-									 iterations,
-									 salt_length,
-									 salt);
-
-		status = ldns_dname_cat(hashed_sname, zone_name);
-                if(status != LDNS_STATUS_OK) {
-	                LDNS_FREE(salt);
-	                ldns_rdf_deep_free(zone_name);
-	                ldns_rdf_deep_free(sname);
-                        return NULL;
-                }
-
-		for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) {
-			nsec = ldns_rr_list_rr(nsec3s, nsec_i);
-
-			/* check values of iterations etc! */
-
-			/* exact match? */
-			if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) {
-			 	exact_match_found = true;
-			} else if (ldns_nsec_covers_name(nsec, hashed_sname)) {
-				in_range_found = true;
-			}
-
-		}
-		if (!exact_match_found && in_range_found) {
-			flag = true;
-		} else if (exact_match_found && flag) {
-			result = ldns_rdf_clone(sname);
-			/* RFC 5155: 8.3. 2.** "The proof is complete" */
-			ldns_rdf_deep_free(hashed_sname);
-			goto done;
-		} else if (exact_match_found && !flag) {
-			/* error! */
-			ldns_rdf_deep_free(hashed_sname);
-			goto done;
-		} else {
-			flag = false;
-		}
-
-		ldns_rdf_deep_free(hashed_sname);
-		tmp = sname;
-		sname = ldns_dname_left_chop(sname);
-		ldns_rdf_deep_free(tmp);
-	}
-
-	done:
-	LDNS_FREE(salt);
-	ldns_rdf_deep_free(zone_name);
-	ldns_rdf_deep_free(sname);
-
-	return result;
-}
-
-bool
-ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt)
-{
-	size_t i;
-	for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
-		if (ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_answer(pkt), i)) ==
-		    LDNS_RR_TYPE_RRSIG) {
-			return true;
-		}
-	}
-	for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
-		if (ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_authority(pkt), i)) ==
-		    LDNS_RR_TYPE_RRSIG) {
-			return true;
-		}
-	}
-	return false;
-}
-
-ldns_rr_list *
-ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt,
-									ldns_rdf *name,
-									ldns_rr_type type)
-{
-	uint16_t t_netorder;
-	ldns_rr_list *sigs;
-	ldns_rr_list *sigs_covered;
-	ldns_rdf *rdf_t;
-	
-	sigs = ldns_pkt_rr_list_by_name_and_type(pkt,
-									 name,
-									 LDNS_RR_TYPE_RRSIG,
-									 LDNS_SECTION_ANY_NOQUESTION
-									 );
-
-	t_netorder = htons(type); /* rdf are in network order! */
-	rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, LDNS_RDF_SIZE_WORD, &t_netorder);
-	sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
-	
-	ldns_rdf_free(rdf_t);
-	ldns_rr_list_deep_free(sigs);
-
-	return sigs_covered;
-
-}
-
-ldns_rr_list *
-ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type)
-{
-	uint16_t t_netorder;
-	ldns_rr_list *sigs;
-	ldns_rr_list *sigs_covered;
-	ldns_rdf *rdf_t;
-
-	sigs = ldns_pkt_rr_list_by_type(pkt,
-	                                LDNS_RR_TYPE_RRSIG,
-	                                LDNS_SECTION_ANY_NOQUESTION
-							  );
-
-	t_netorder = htons(type); /* rdf are in network order! */
-	rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE,
-					 2,
-					 &t_netorder);
-	sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
-
-	ldns_rdf_free(rdf_t);
-	ldns_rr_list_deep_free(sigs);
-
-	return sigs_covered;
-
-}
-
-/* used only on the public key RR */
-uint16_t
-ldns_calc_keytag(const ldns_rr *key)
-{
-	uint16_t ac16;
-	ldns_buffer *keybuf;
-	size_t keysize;
-
-	if (!key) {
-		return 0;
-	}
-
-	if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY &&
-	    ldns_rr_get_type(key) != LDNS_RR_TYPE_KEY
-	    ) {
-		return 0;
-	}
-
-	/* rdata to buf - only put the rdata in a buffer */
-	keybuf = ldns_buffer_new(LDNS_MIN_BUFLEN); /* grows */
-	if (!keybuf) {
-		return 0;
-	}
-	(void)ldns_rr_rdata2buffer_wire(keybuf, key);
-	/* the current pos in the buffer is the keysize */
-	keysize= ldns_buffer_position(keybuf);
-
-	ac16 = ldns_calc_keytag_raw(ldns_buffer_begin(keybuf), keysize);
-	ldns_buffer_free(keybuf);
-	return ac16;
-}
-
-uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize)
-{
-	unsigned int i;
-	uint32_t ac32;
-	uint16_t ac16;
-
-	if(keysize < 4) {
-		return 0;
-	}
-	/* look at the algorithm field, copied from 2535bis */
-	if (key[3] == LDNS_RSAMD5) {
-		ac16 = 0;
-		if (keysize > 4) {
-			memmove(&ac16, key + keysize - 3, 2);
-		}
-		ac16 = ntohs(ac16);
-		return (uint16_t) ac16;
-	} else {
-		ac32 = 0;
-		for (i = 0; (size_t)i < keysize; ++i) {
-			ac32 += (i & 1) ? key[i] : key[i] << 8;
-		}
-		ac32 += (ac32 >> 16) & 0xFFFF;
-		return (uint16_t) (ac32 & 0xFFFF);
-	}
-}
-
-#ifdef HAVE_SSL
-DSA *
-ldns_key_buf2dsa(ldns_buffer *key)
-{
-	return ldns_key_buf2dsa_raw((unsigned char*)ldns_buffer_begin(key),
-						   ldns_buffer_position(key));
-}
-
-DSA *
-ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
-{
-	uint8_t T;
-	uint16_t length;
-	uint16_t offset;
-	DSA *dsa;
-	BIGNUM *Q; BIGNUM *P;
-	BIGNUM *G; BIGNUM *Y;
-
-	if(len == 0)
-		return NULL;
-	T = (uint8_t)key[0];
-	length = (64 + T * 8);
-	offset = 1;
-
-	if (T > 8) {
-		return NULL;
-	}
-	if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
-		return NULL;
-
-	Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
-	offset += SHA_DIGEST_LENGTH;
-
-	P = BN_bin2bn(key+offset, (int)length, NULL);
-	offset += length;
-
-	G = BN_bin2bn(key+offset, (int)length, NULL);
-	offset += length;
-
-	Y = BN_bin2bn(key+offset, (int)length, NULL);
-	offset += length;
-
-	/* create the key and set its properties */
-	if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
-		BN_free(Q);
-		BN_free(P);
-		BN_free(G);
-		BN_free(Y);
-		return NULL;
-	}
-#ifndef S_SPLINT_S
-	dsa->p = P;
-	dsa->q = Q;
-	dsa->g = G;
-	dsa->pub_key = Y;
-#endif /* splint */
-
-	return dsa;
-}
-
-RSA *
-ldns_key_buf2rsa(ldns_buffer *key)
-{
-	return ldns_key_buf2rsa_raw((unsigned char*)ldns_buffer_begin(key),
-						   ldns_buffer_position(key));
-}
-
-RSA *
-ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
-{
-	uint16_t offset;
-	uint16_t exp;
-	uint16_t int16;
-	RSA *rsa;
-	BIGNUM *modulus;
-	BIGNUM *exponent;
-
-	if (len == 0)
-		return NULL;
-	if (key[0] == 0) {
-		if(len < 3)
-			return NULL;
-		/* need some smart comment here XXX*/
-		/* the exponent is too large so it's places
-		 * futher...???? */
-		memmove(&int16, key+1, 2);
-		exp = ntohs(int16);
-		offset = 3;
-	} else {
-		exp = key[0];
-		offset = 1;
-	}
-
-	/* key length at least one */
-	if(len < (size_t)offset + exp + 1)
-		return NULL;
-
-	/* Exponent */
-	exponent = BN_new();
-	if(!exponent) return NULL;
-	(void) BN_bin2bn(key+offset, (int)exp, exponent);
-	offset += exp;
-
-	/* Modulus */
-	modulus = BN_new();
-	if(!modulus) {
-		BN_free(exponent);
-		return NULL;
-	}
-	/* length of the buffer must match the key length! */
-	(void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
-
-	rsa = RSA_new();
-	if(!rsa) {
-		BN_free(exponent);
-		BN_free(modulus);
-		return NULL;
-	}
-#ifndef S_SPLINT_S
-	rsa->n = modulus;
-	rsa->e = exponent;
-#endif /* splint */
-
-	return rsa;
-}
-
-int
-ldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
-	const EVP_MD* md)
-{
-	EVP_MD_CTX* ctx;
-	ctx = EVP_MD_CTX_create();
-	if(!ctx)
-		return false;
-	if(!EVP_DigestInit_ex(ctx, md, NULL) ||
-		!EVP_DigestUpdate(ctx, data, len) ||
-		!EVP_DigestFinal_ex(ctx, dest, NULL)) {
-		EVP_MD_CTX_destroy(ctx);
-		return false;
-	}
-	EVP_MD_CTX_destroy(ctx);
-	return true;
-}
-#endif /* HAVE_SSL */
-
-ldns_rr *
-ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
-{
-	ldns_rdf *tmp;
-	ldns_rr *ds;
-	uint16_t keytag;
-	uint8_t  sha1hash;
-	uint8_t *digest;
-	ldns_buffer *data_buf;
-#ifdef USE_GOST
-	const EVP_MD* md = NULL;
-#endif
-
-	if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY) {
-		return NULL;
-	}
-
-	ds = ldns_rr_new();
-	if (!ds) {
-		return NULL;
-	}
-	ldns_rr_set_type(ds, LDNS_RR_TYPE_DS);
-	ldns_rr_set_owner(ds, ldns_rdf_clone(
-								  ldns_rr_owner(key)));
-	ldns_rr_set_ttl(ds, ldns_rr_ttl(key));
-	ldns_rr_set_class(ds, ldns_rr_get_class(key));
-
-	switch(h) {
-	default:
-	case LDNS_SHA1:
-		digest = LDNS_XMALLOC(uint8_t, LDNS_SHA1_DIGEST_LENGTH);
-		if (!digest) {
-			ldns_rr_free(ds);
-			return NULL;
-		}
-		break;
-	case LDNS_SHA256:
-		digest = LDNS_XMALLOC(uint8_t, LDNS_SHA256_DIGEST_LENGTH);
-		if (!digest) {
-			ldns_rr_free(ds);
-			return NULL;
-		}
-		break;
-	case LDNS_HASH_GOST:
-#ifdef USE_GOST
-		(void)ldns_key_EVP_load_gost_id();
-		md = EVP_get_digestbyname("md_gost94");
-		if(!md) {
-			ldns_rr_free(ds);
-			return NULL;
-		}
-		digest = LDNS_XMALLOC(uint8_t, EVP_MD_size(md));
-		if (!digest) {
-			ldns_rr_free(ds);
-			return NULL;
-		}
-                break;
-#else
-		/* not implemented */
-		ldns_rr_free(ds);
-		return NULL;
-#endif
-	case LDNS_SHA384:
-#ifdef USE_ECDSA
-		digest = LDNS_XMALLOC(uint8_t, SHA384_DIGEST_LENGTH);
-		if (!digest) {
-			ldns_rr_free(ds);
-			return NULL;
-		}
-                break;
-#else
-		/* not implemented */
-		ldns_rr_free(ds);
-		return NULL;
-#endif
-	}
-
-	data_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	if (!data_buf) {
-		LDNS_FREE(digest);
-		ldns_rr_free(ds);
-		return NULL;
-	}
-
-	/* keytag */
-	keytag = htons(ldns_calc_keytag((ldns_rr*)key));
-	tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16,
-						   sizeof(uint16_t),
-						   &keytag);
-	ldns_rr_push_rdf(ds, tmp);
-
-	/* copy the algorithm field */
-	if ((tmp = ldns_rr_rdf(key, 2)) == NULL) {
-		LDNS_FREE(digest);
-		ldns_buffer_free(data_buf);
-		ldns_rr_free(ds);
-		return NULL;
-	} else {
-		ldns_rr_push_rdf(ds, ldns_rdf_clone( tmp )); 
-	}
-
-	/* digest hash type */
-	sha1hash = (uint8_t)h;
-	tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8,
-						   sizeof(uint8_t),
-						   &sha1hash);
-	ldns_rr_push_rdf(ds, tmp);
-
-	/* digest */
-	/* owner name */
-	tmp = ldns_rdf_clone(ldns_rr_owner(key));
-	ldns_dname2canonical(tmp);
-	if (ldns_rdf2buffer_wire(data_buf, tmp) != LDNS_STATUS_OK) {
-		LDNS_FREE(digest);
-		ldns_buffer_free(data_buf);
-		ldns_rr_free(ds);
-		ldns_rdf_deep_free(tmp);
-		return NULL;
-	}
-	ldns_rdf_deep_free(tmp);
-
-	/* all the rdata's */
-	if (ldns_rr_rdata2buffer_wire(data_buf,
-							(ldns_rr*)key) != LDNS_STATUS_OK) {
-		LDNS_FREE(digest);
-		ldns_buffer_free(data_buf);
-		ldns_rr_free(ds);
-		return NULL;
-	}
-	switch(h) {
-	case LDNS_SHA1:
-		(void) ldns_sha1((unsigned char *) ldns_buffer_begin(data_buf),
-		                 (unsigned int) ldns_buffer_position(data_buf),
-		                 (unsigned char *) digest);
-
-		tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
-		                            LDNS_SHA1_DIGEST_LENGTH,
-		                            digest);
-		ldns_rr_push_rdf(ds, tmp);
-
-		break;
-	case LDNS_SHA256:
-		(void) ldns_sha256((unsigned char *) ldns_buffer_begin(data_buf),
-		                   (unsigned int) ldns_buffer_position(data_buf),
-		                   (unsigned char *) digest);
-		tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
-		                            LDNS_SHA256_DIGEST_LENGTH,
-		                            digest);
-		ldns_rr_push_rdf(ds, tmp);
-		break;
-	case LDNS_HASH_GOST:
-#ifdef USE_GOST
-		if(!ldns_digest_evp((unsigned char *) ldns_buffer_begin(data_buf),
-				(unsigned int) ldns_buffer_position(data_buf),
-				(unsigned char *) digest, md)) {
-			LDNS_FREE(digest);
-			ldns_buffer_free(data_buf);
-			ldns_rr_free(ds);
-			return NULL;
-		}
-		tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
-		                            (size_t)EVP_MD_size(md),
-		                            digest);
-		ldns_rr_push_rdf(ds, tmp);
-#endif
-		break;
-	case LDNS_SHA384:
-#ifdef USE_ECDSA
-		(void) SHA384((unsigned char *) ldns_buffer_begin(data_buf),
-		                 (unsigned int) ldns_buffer_position(data_buf),
-		                 (unsigned char *) digest);
-		tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
-		                            SHA384_DIGEST_LENGTH,
-		                            digest);
-		ldns_rr_push_rdf(ds, tmp);
-#endif
-		break;
-	}
-
-	LDNS_FREE(digest);
-	ldns_buffer_free(data_buf);
-	return ds;
-}
-
-/* From RFC3845:
- *
- * 2.1.2.  The List of Type Bit Map(s) Field
- * 
- *    The RR type space is split into 256 window blocks, each representing
- *    the low-order 8 bits of the 16-bit RR type space.  Each block that
- *    has at least one active RR type is encoded using a single octet
- *    window number (from 0 to 255), a single octet bitmap length (from 1
- *    to 32) indicating the number of octets used for the window block's
- *    bitmap, and up to 32 octets (256 bits) of bitmap.
- * 
- *    Window blocks are present in the NSEC RR RDATA in increasing
- *    numerical order.
- * 
- *    "|" denotes concatenation
- * 
- *    Type Bit Map(s) Field = ( Window Block # | Bitmap Length | Bitmap ) +
- * 
- *    <cut>
- * 
- *    Blocks with no types present MUST NOT be included.  Trailing zero
- *    octets in the bitmap MUST be omitted.  The length of each block's
- *    bitmap is determined by the type code with the largest numerical
- *    value within that block, among the set of RR types present at the
- *    NSEC RR's owner name.  Trailing zero octets not specified MUST be
- *    interpreted as zero octets.
- */
-ldns_rdf *
-ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
-                               size_t size,
-                               ldns_rr_type nsec_type)
-{
-	uint8_t  window;		/*  most significant octet of type */
-	uint8_t  subtype;		/* least significant octet of type */
-	uint16_t windows[256]		/* Max subtype per window */
-#ifndef S_SPLINT_S
-	                      = { 0 }	/* Initialize ALL elements with 0 */
-#endif
-	                             ;
-	ldns_rr_type* d;	/* used to traverse rr_type_list*/
-	size_t i;		/* used to traverse windows array */
-
-	size_t sz;			/* size needed for type bitmap rdf */
-	uint8_t* data = NULL;		/* rdf data */
-	uint8_t* dptr;			/* used to itraverse rdf data */
-	ldns_rdf* rdf;			/* bitmap rdf to return */
-
-	if (nsec_type != LDNS_RR_TYPE_NSEC &&
-	    nsec_type != LDNS_RR_TYPE_NSEC3) {
-		return NULL;
-	}
-
-	/* Which other windows need to be in the bitmap rdf?
-	 */
-	for (d = rr_type_list; d < rr_type_list + size; d++) {
-		window  = *d >> 8;
-		subtype = *d & 0xff;
-		if (windows[window] < subtype) {
-			windows[window] = subtype;
-		}
-	}
-
-	/* How much space do we need in the rdf for those windows?
-	 */
-	sz = 0;
-	for (i = 0; i < 256; i++) {
-		if (windows[i]) {
-			sz += windows[i] / 8 + 3;
-		}
-	}
-	if (sz > 0) {
-		/* Format rdf data according RFC3845 Section 2.1.2 (see above)
-		 */
-		dptr = data = LDNS_CALLOC(uint8_t, sz);
-		if (!data) {
-			return NULL;
-		}
-		for (i = 0; i < 256; i++) {
-			if (windows[i]) {
-				*dptr++ = (uint8_t)i;
-				*dptr++ = (uint8_t)(windows[i] / 8 + 1);
-
-				/* Now let windows[i] index the bitmap
-				 * within data
-				 */
-				windows[i] = (uint16_t)(dptr - data);
-
-				dptr += dptr[-1];
-			}
-		}
-	}
-
-	/* Set the bits?
-	 */
-	for (d = rr_type_list; d < rr_type_list + size; d++) {
-		subtype = *d & 0xff;
-		data[windows[*d >> 8] + subtype/8] |= (0x80 >> (subtype % 8));
-	}
-
-	/* Allocate and return rdf structure for the data
-	 */
-	rdf = ldns_rdf_new(LDNS_RDF_TYPE_BITMAP, sz, data);
-	if (!rdf) {
-		LDNS_FREE(data);
-		return NULL;
-	}
-	return rdf;
-}
-
-int
-ldns_dnssec_rrsets_contains_type(ldns_dnssec_rrsets *rrsets,
-                                 ldns_rr_type type)
-{
-	ldns_dnssec_rrsets *cur_rrset = rrsets;
-	while (cur_rrset) {
-		if (cur_rrset->type == type) {
-			return 1;
-		}
-		cur_rrset = cur_rrset->next;
-	}
-	return 0;
-}
-
-ldns_rr *
-ldns_dnssec_create_nsec(ldns_dnssec_name *from,
-                        ldns_dnssec_name *to,
-                        ldns_rr_type nsec_type)
-{
-	ldns_rr *nsec_rr;
-	ldns_rr_type types[65536];
-	size_t type_count = 0;
-	ldns_dnssec_rrsets *cur_rrsets;
-	int on_delegation_point;
-
-	if (!from || !to || (nsec_type != LDNS_RR_TYPE_NSEC)) {
-		return NULL;
-	}
-
-	nsec_rr = ldns_rr_new();
-	ldns_rr_set_type(nsec_rr, nsec_type);
-	ldns_rr_set_owner(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(from)));
-	ldns_rr_push_rdf(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(to)));
-
-	on_delegation_point = ldns_dnssec_rrsets_contains_type(
-			from->rrsets, LDNS_RR_TYPE_NS)
-		&& !ldns_dnssec_rrsets_contains_type(
-			from->rrsets, LDNS_RR_TYPE_SOA);
-
-	cur_rrsets = from->rrsets;
-	while (cur_rrsets) {
-		/* Do not include non-authoritative rrsets on the delegation point
-		 * in the type bitmap */
-		if ((on_delegation_point && (
-				cur_rrsets->type == LDNS_RR_TYPE_NS 
-			     || cur_rrsets->type == LDNS_RR_TYPE_DS))
-			|| (!on_delegation_point &&
-				cur_rrsets->type != LDNS_RR_TYPE_RRSIG
-			     && cur_rrsets->type != LDNS_RR_TYPE_NSEC)) {
-
-			types[type_count] = cur_rrsets->type;
-			type_count++;
-		}
-		cur_rrsets = cur_rrsets->next;
-
-	}
-	types[type_count] = LDNS_RR_TYPE_RRSIG;
-	type_count++;
-	types[type_count] = LDNS_RR_TYPE_NSEC;
-	type_count++;
-
-	ldns_rr_push_rdf(nsec_rr, ldns_dnssec_create_nsec_bitmap(types,
-	                               type_count,
-	                               nsec_type));
-
-	return nsec_rr;
-}
-
-ldns_rr *
-ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
-					ldns_dnssec_name *to,
-					ldns_rdf *zone_name,
-					uint8_t algorithm,
-					uint8_t flags,
-					uint16_t iterations,
-					uint8_t salt_length,
-					uint8_t *salt)
-{
-	ldns_rr *nsec_rr;
-	ldns_rr_type types[65536];
-	size_t type_count = 0;
-	ldns_dnssec_rrsets *cur_rrsets;
-	ldns_status status;
-	int on_delegation_point;
-
-	if (!from) {
-		return NULL;
-	}
-
-	nsec_rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3);
-	ldns_rr_set_owner(nsec_rr,
-	                  ldns_nsec3_hash_name(ldns_dnssec_name_name(from),
-	                  algorithm,
-	                  iterations,
-	                  salt_length,
-	                  salt));
-	status = ldns_dname_cat(ldns_rr_owner(nsec_rr), zone_name);
-        if(status != LDNS_STATUS_OK) {
-                ldns_rr_free(nsec_rr);
-                return NULL;
-        }
-	ldns_nsec3_add_param_rdfs(nsec_rr,
-	                          algorithm,
-	                          flags,
-	                          iterations,
-	                          salt_length,
-	                          salt);
-
-	on_delegation_point = ldns_dnssec_rrsets_contains_type(
-			from->rrsets, LDNS_RR_TYPE_NS)
-		&& !ldns_dnssec_rrsets_contains_type(
-			from->rrsets, LDNS_RR_TYPE_SOA);
-	cur_rrsets = from->rrsets;
-	while (cur_rrsets) {
-		/* Do not include non-authoritative rrsets on the delegation point
-		 * in the type bitmap. Potentionally not skipping insecure
-		 * delegation should have been done earlier, in function
-		 * ldns_dnssec_zone_create_nsec3s, or even earlier in:
-		 * ldns_dnssec_zone_sign_nsec3_flg .
-		 */
-		if ((on_delegation_point && (
-				cur_rrsets->type == LDNS_RR_TYPE_NS
-			     || cur_rrsets->type == LDNS_RR_TYPE_DS))
-			|| (!on_delegation_point &&
-				cur_rrsets->type != LDNS_RR_TYPE_RRSIG)) {
-
-			types[type_count] = cur_rrsets->type;
-			type_count++;
-		}
-		cur_rrsets = cur_rrsets->next;
-	}
-	/* always add rrsig type if this is not an unsigned
-	 * delegation
-	 */
-	if (type_count > 0 &&
-	    !(type_count == 1 && types[0] == LDNS_RR_TYPE_NS)) {
-		types[type_count] = LDNS_RR_TYPE_RRSIG;
-		type_count++;
-	}
-
-	/* leave next rdata empty if they weren't precomputed yet */
-	if (to && to->hashed_name) {
-		(void) ldns_rr_set_rdf(nsec_rr,
-		                       ldns_rdf_clone(to->hashed_name),
-		                       4);
-	} else {
-		(void) ldns_rr_set_rdf(nsec_rr, NULL, 4);
-	}
-
-	ldns_rr_push_rdf(nsec_rr,
-	                 ldns_dnssec_create_nsec_bitmap(types,
-	                 type_count,
-	                 LDNS_RR_TYPE_NSEC3));
-
-	return nsec_rr;
-}
-
-ldns_rr *
-ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs)
-{
-	/* we do not do any check here - garbage in, garbage out */
-
-	/* the the start and end names - get the type from the
-	 * before rrlist */
-
-	/* inefficient, just give it a name, a next name, and a list of rrs */
-	/* we make 1 big uberbitmap first, then windows */
-	/* todo: make something more efficient :) */
-	uint16_t i;
-	ldns_rr *i_rr;
-	uint16_t i_type;
-
-	ldns_rr *nsec = NULL;
-	ldns_rr_type i_type_list[65536];
-	size_t type_count = 0;
-
-	nsec = ldns_rr_new();
-	ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC);
-	ldns_rr_set_owner(nsec, ldns_rdf_clone(cur_owner));
-	ldns_rr_push_rdf(nsec, ldns_rdf_clone(next_owner));
-
-	for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
-		i_rr = ldns_rr_list_rr(rrs, i);
-		if (ldns_rdf_compare(cur_owner,
-						 ldns_rr_owner(i_rr)) == 0) {
-			i_type = ldns_rr_get_type(i_rr);
-			if (i_type != LDNS_RR_TYPE_RRSIG && i_type != LDNS_RR_TYPE_NSEC) {
-				if (type_count == 0 || i_type_list[type_count-1] != i_type) {
-					i_type_list[type_count] = i_type;
-					type_count++;
-				}
-			}
-		}
-	}
-
-	i_type_list[type_count] = LDNS_RR_TYPE_RRSIG;
-	type_count++;
-	i_type_list[type_count] = LDNS_RR_TYPE_NSEC;
-	type_count++;
-
-	ldns_rr_push_rdf(nsec,
-				  ldns_dnssec_create_nsec_bitmap(i_type_list,
-						type_count, LDNS_RR_TYPE_NSEC));
-
-	return nsec;
-}
-
-ldns_rdf *
-ldns_nsec3_hash_name(ldns_rdf *name,
-				 uint8_t algorithm,
-				 uint16_t iterations,
-				 uint8_t salt_length,
-				 uint8_t *salt)
-{
-	size_t hashed_owner_str_len;
-	ldns_rdf *cann;
-	ldns_rdf *hashed_owner;
-	unsigned char *hashed_owner_str;
-	char *hashed_owner_b32;
-	size_t hashed_owner_b32_len;
-	uint32_t cur_it;
-	/* define to contain the largest possible hash, which is
-	 * sha1 at the moment */
-	unsigned char hash[LDNS_SHA1_DIGEST_LENGTH];
-	ldns_status status;
-
-	/* TODO: mnemonic list for hash algs SHA-1, default to 1 now (sha1) */
-	if (algorithm != LDNS_SHA1) {
-		return NULL;
-	}
-
-	/* prepare the owner name according to the draft section bla */
-	cann = ldns_rdf_clone(name);
-	if(!cann) {
-#ifdef STDERR_MSGS
-		fprintf(stderr, "Memory error\n");
-#endif
-		return NULL;
-	}
-	ldns_dname2canonical(cann);
-
-	hashed_owner_str_len = salt_length + ldns_rdf_size(cann);
-	hashed_owner_str = LDNS_XMALLOC(unsigned char, hashed_owner_str_len);
-        if(!hashed_owner_str) {
-	        ldns_rdf_deep_free(cann);
-                return NULL;
-        }
-	memcpy(hashed_owner_str, ldns_rdf_data(cann), ldns_rdf_size(cann));
-	memcpy(hashed_owner_str + ldns_rdf_size(cann), salt, salt_length);
-	ldns_rdf_deep_free(cann);
-
-	for (cur_it = iterations + 1; cur_it > 0; cur_it--) {
-		(void) ldns_sha1((unsigned char *) hashed_owner_str,
-		                 (unsigned int) hashed_owner_str_len, hash);
-
-		LDNS_FREE(hashed_owner_str);
-		hashed_owner_str_len = salt_length + LDNS_SHA1_DIGEST_LENGTH;
-		hashed_owner_str = LDNS_XMALLOC(unsigned char, hashed_owner_str_len);
-		if (!hashed_owner_str) {
-			return NULL;
-		}
-		memcpy(hashed_owner_str, hash, LDNS_SHA1_DIGEST_LENGTH);
-		memcpy(hashed_owner_str + LDNS_SHA1_DIGEST_LENGTH, salt, salt_length);
-		hashed_owner_str_len = LDNS_SHA1_DIGEST_LENGTH + salt_length;
-	}
-
-	LDNS_FREE(hashed_owner_str);
-	hashed_owner_str = hash;
-	hashed_owner_str_len = LDNS_SHA1_DIGEST_LENGTH;
-
-	hashed_owner_b32 = LDNS_XMALLOC(char,
-                  ldns_b32_ntop_calculate_size(hashed_owner_str_len) + 1);
-        if(!hashed_owner_b32) {
-                return NULL;
-        }
-        hashed_owner_b32_len = (size_t) ldns_b32_ntop_extended_hex(
-                (uint8_t *) hashed_owner_str,
-                hashed_owner_str_len,
-                hashed_owner_b32,
-                ldns_b32_ntop_calculate_size(hashed_owner_str_len)+1);
-	if (hashed_owner_b32_len < 1) {
-#ifdef STDERR_MSGS
-		fprintf(stderr, "Error in base32 extended hex encoding ");
-		fprintf(stderr, "of hashed owner name (name: ");
-		ldns_rdf_print(stderr, name);
-		fprintf(stderr, ", return code: %u)\n",
-		        (unsigned int) hashed_owner_b32_len);
-#endif
-		LDNS_FREE(hashed_owner_b32);
-		return NULL;
-	}
-	hashed_owner_b32[hashed_owner_b32_len] = '\0';
-
-	status = ldns_str2rdf_dname(&hashed_owner, hashed_owner_b32);
-	if (status != LDNS_STATUS_OK) {
-#ifdef STDERR_MSGS
-		fprintf(stderr, "Error creating rdf from %s\n", hashed_owner_b32);
-#endif
-		LDNS_FREE(hashed_owner_b32);
-		return NULL;
-	}
-
-	LDNS_FREE(hashed_owner_b32);
-	return hashed_owner;
-}
-
-void
-ldns_nsec3_add_param_rdfs(ldns_rr *rr,
-					 uint8_t algorithm,
-					 uint8_t flags,
-					 uint16_t iterations,
-					 uint8_t salt_length,
-					 uint8_t *salt)
-{
-	ldns_rdf *salt_rdf = NULL;
-	uint8_t *salt_data = NULL;
-	ldns_rdf *old;
-
-	old = ldns_rr_set_rdf(rr,
-	                      ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8,
-	                                            1, (void*)&algorithm),
-	                      0);
-	if (old) ldns_rdf_deep_free(old);
-
-	old = ldns_rr_set_rdf(rr,
-	                      ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8,
-	                                            1, (void*)&flags),
-	                      1);
-	if (old) ldns_rdf_deep_free(old);
-
-	old = ldns_rr_set_rdf(rr,
-                          ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
-                                                iterations),
-	                      2);
-	if (old) ldns_rdf_deep_free(old);
-
-	salt_data = LDNS_XMALLOC(uint8_t, salt_length + 1);
-        if(!salt_data) {
-                /* no way to return error */
-                return;
-        }
-	salt_data[0] = salt_length;
-	memcpy(salt_data + 1, salt, salt_length);
-	salt_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT,
-							   salt_length + 1,
-							   salt_data);
-        if(!salt_rdf) {
-                LDNS_FREE(salt_data);
-                /* no way to return error */
-                return;
-        }
-
-	old = ldns_rr_set_rdf(rr, salt_rdf, 3);
-	if (old) ldns_rdf_deep_free(old);
-	LDNS_FREE(salt_data);
-}
-
-static int
-rr_list_delegation_only(ldns_rdf *origin, ldns_rr_list *rr_list)
-{
-	size_t i;
-	ldns_rr *cur_rr;
-	if (!origin || !rr_list) return 0;
-	for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
-		cur_rr = ldns_rr_list_rr(rr_list, i);
-		if (ldns_dname_compare(ldns_rr_owner(cur_rr), origin) == 0) {
-			return 0;
-		}
-		if (ldns_rr_get_type(cur_rr) != LDNS_RR_TYPE_NS) {
-			return 0;
-		}
-	}
-	return 1;
-}
-
-/* this will NOT return the NSEC3  completed, you will have to run the
-   finalize function on the rrlist later! */
-ldns_rr *
-ldns_create_nsec3(ldns_rdf *cur_owner,
-                  ldns_rdf *cur_zone,
-                  ldns_rr_list *rrs,
-                  uint8_t algorithm,
-                  uint8_t flags,
-                  uint16_t iterations,
-                  uint8_t salt_length,
-                  uint8_t *salt,
-                  bool emptynonterminal)
-{
-	size_t i;
-	ldns_rr *i_rr;
-	uint16_t i_type;
-
-	ldns_rr *nsec = NULL;
-	ldns_rdf *hashed_owner = NULL;
-
-	ldns_status status;
-
-    ldns_rr_type i_type_list[1024];
-	size_t type_count = 0;
-
-	hashed_owner = ldns_nsec3_hash_name(cur_owner,
-								 algorithm,
-								 iterations,
-								 salt_length,
-								 salt);
-	status = ldns_dname_cat(hashed_owner, cur_zone);
-        if(status != LDNS_STATUS_OK) {
-		ldns_rdf_deep_free(hashed_owner);
-                return NULL;
-	}
-	nsec = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3);
-        if(!nsec) {
-		ldns_rdf_deep_free(hashed_owner);
-                return NULL;
-	}
-	ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC3);
-	ldns_rr_set_owner(nsec, hashed_owner);
-
-	ldns_nsec3_add_param_rdfs(nsec,
-						 algorithm,
-						 flags,
-						 iterations,
-						 salt_length,
-						 salt);
-	(void) ldns_rr_set_rdf(nsec, NULL, 4);
-
-
-	for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
-		i_rr = ldns_rr_list_rr(rrs, i);
-		if (ldns_rdf_compare(cur_owner,
-						 ldns_rr_owner(i_rr)) == 0) {
-			i_type = ldns_rr_get_type(i_rr);
-			if (type_count == 0 || i_type_list[type_count-1] != i_type) {
-				i_type_list[type_count] = i_type;
-				type_count++;
-			}
-		}
-	}
-
-	/* add RRSIG anyway, but only if this is not an ENT or
-	 * an unsigned delegation */
-	if (!emptynonterminal && !rr_list_delegation_only(cur_zone, rrs)) {
-		i_type_list[type_count] = LDNS_RR_TYPE_RRSIG;
-		type_count++;
-	}
-
-	/* and SOA if owner == zone */
-	if (ldns_dname_compare(cur_zone, cur_owner) == 0) {
-		i_type_list[type_count] = LDNS_RR_TYPE_SOA;
-		type_count++;
-	}
-
-	ldns_rr_push_rdf(nsec,
-				  ldns_dnssec_create_nsec_bitmap(i_type_list,
-						type_count, LDNS_RR_TYPE_NSEC3));
-
-	return nsec;
-}
-
-uint8_t
-ldns_nsec3_algorithm(const ldns_rr *nsec3_rr)
-{
-	if (nsec3_rr && 
-	      (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
-	       ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
-	    && (ldns_rr_rdf(nsec3_rr, 0) != NULL)
-	    && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 0)) > 0) {
-		return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 0));
-	}
-	return 0;
-}
-
-uint8_t
-ldns_nsec3_flags(const ldns_rr *nsec3_rr)
-{
-	if (nsec3_rr && 
-	      (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
-	       ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
-	    && (ldns_rr_rdf(nsec3_rr, 1) != NULL)
-	    && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 1)) > 0) {
-		return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 1));
-	}
-	return 0;
-}
-
-bool
-ldns_nsec3_optout(const ldns_rr *nsec3_rr)
-{
-	return (ldns_nsec3_flags(nsec3_rr) & LDNS_NSEC3_VARS_OPTOUT_MASK);
-}
-
-uint16_t
-ldns_nsec3_iterations(const ldns_rr *nsec3_rr)
-{
-	if (nsec3_rr &&
-	      (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
-	       ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
-	    && (ldns_rr_rdf(nsec3_rr, 2) != NULL)
-	    && ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 2)) > 0) {
-		return ldns_rdf2native_int16(ldns_rr_rdf(nsec3_rr, 2));
-	}
-	return 0;
-	
-}
-
-ldns_rdf *
-ldns_nsec3_salt(const ldns_rr *nsec3_rr)
-{
-	if (nsec3_rr && 
-	      (ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 ||
-	       ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3PARAM)
-	    ) {
-		return ldns_rr_rdf(nsec3_rr, 3);
-	}
-	return NULL;
-}
-
-uint8_t
-ldns_nsec3_salt_length(const ldns_rr *nsec3_rr)
-{
-	ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr);
-	if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) {
-		return (uint8_t) ldns_rdf_data(salt_rdf)[0];
-	}
-	return 0;
-}
-
-/* allocs data, free with LDNS_FREE() */
-uint8_t *
-ldns_nsec3_salt_data(const ldns_rr *nsec3_rr)
-{
-	uint8_t salt_length;
-	uint8_t *salt;
-
-	ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr);
-	if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) {
-	    	salt_length = ldns_rdf_data(salt_rdf)[0];
-		salt = LDNS_XMALLOC(uint8_t, salt_length);
-                if(!salt) return NULL;
-		memcpy(salt, &ldns_rdf_data(salt_rdf)[1], salt_length);
-		return salt;
-	}
-	return NULL;
-}
-
-ldns_rdf *
-ldns_nsec3_next_owner(const ldns_rr *nsec3_rr)
-{
-	if (!nsec3_rr || ldns_rr_get_type(nsec3_rr) != LDNS_RR_TYPE_NSEC3) {
-		return NULL;
-	} else {
-		return ldns_rr_rdf(nsec3_rr, 4);
-	}
-}
-
-ldns_rdf *
-ldns_nsec3_bitmap(const ldns_rr *nsec3_rr)
-{
-	if (!nsec3_rr || ldns_rr_get_type(nsec3_rr) != LDNS_RR_TYPE_NSEC3) {
-		return NULL;
-	} else {
-		return ldns_rr_rdf(nsec3_rr, 5);
-	}
-}
-
-ldns_rdf *
-ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name)
-{
-	uint8_t algorithm;
-	uint16_t iterations;
-	uint8_t salt_length;
-	uint8_t *salt = 0;
-
-	ldns_rdf *hashed_owner;
-
-	algorithm = ldns_nsec3_algorithm(nsec);
-	salt_length = ldns_nsec3_salt_length(nsec);
-	salt = ldns_nsec3_salt_data(nsec);
-	iterations = ldns_nsec3_iterations(nsec);
-
-	hashed_owner = ldns_nsec3_hash_name(name,
-								 algorithm,
-								 iterations,
-								 salt_length,
-								 salt);
-
-	LDNS_FREE(salt);
-	return hashed_owner;
-}
-
-bool
-ldns_nsec_bitmap_covers_type(const  ldns_rdf* bitmap, ldns_rr_type type)
-{
-	uint8_t* dptr;
-	uint8_t* dend;
-
-	/* From RFC3845 Section 2.1.2:
-	 *
-	 *	"The RR type space is split into 256 window blocks, each re-
-	 *	 presenting the low-order 8 bits of the 16-bit RR type space."
-	 */
-	uint8_t  window = type >> 8;
-	uint8_t subtype = type & 0xff;
-
-	if (! bitmap) {
-		return false;
-	}
-	assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
-
-	dptr = ldns_rdf_data(bitmap);
-	dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
-
-	/* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
-	 *                 dptr[0]          dptr[1]         dptr[2:]
-	 */
-	while (dptr < dend && dptr[0] <= window) {
-
-		if (dptr[0] == window && subtype / 8 < dptr[1] &&
-				dptr + dptr[1] + 2 <= dend) {
-
-			return dptr[2 + subtype / 8] & (0x80 >> (subtype % 8));
-		}
-		dptr += dptr[1] + 2; /* next window */
-	}
-	return false;
-}
-
-ldns_status
-ldns_nsec_bitmap_set_type(ldns_rdf* bitmap, ldns_rr_type type)
-{
-	uint8_t* dptr;
-	uint8_t* dend;
-
-	/* From RFC3845 Section 2.1.2:
-	 *
-	 *	"The RR type space is split into 256 window blocks, each re-
-	 *	 presenting the low-order 8 bits of the 16-bit RR type space."
-	 */
-	uint8_t  window = type >> 8;
-	uint8_t subtype = type & 0xff;
-
-	if (! bitmap) {
-		return false;
-	}
-	assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
-
-	dptr = ldns_rdf_data(bitmap);
-	dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
-
-	/* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
-	 *                 dptr[0]          dptr[1]         dptr[2:]
-	 */
-	while (dptr < dend && dptr[0] <= window) {
-
-		if (dptr[0] == window && subtype / 8 < dptr[1] &&
-				dptr + dptr[1] + 2 <= dend) {
-
-			dptr[2 + subtype / 8] |= (0x80 >> (subtype % 8));
-			return LDNS_STATUS_OK;
-		}
-		dptr += dptr[1] + 2; /* next window */
-	}
-	return LDNS_STATUS_TYPE_NOT_IN_BITMAP;
-}
-
-ldns_status
-ldns_nsec_bitmap_clear_type(ldns_rdf* bitmap, ldns_rr_type type)
-{
-	uint8_t* dptr;
-	uint8_t* dend;
-
-	/* From RFC3845 Section 2.1.2:
-	 *
-	 *	"The RR type space is split into 256 window blocks, each re-
-	 *	 presenting the low-order 8 bits of the 16-bit RR type space."
-	 */
-	uint8_t  window = type >> 8;
-	uint8_t subtype = type & 0xff;
-
-	if (! bitmap) {
-		return false;
-	}
-
-	assert(ldns_rdf_get_type(bitmap) == LDNS_RDF_TYPE_BITMAP);
-
-	dptr = ldns_rdf_data(bitmap);
-	dend = ldns_rdf_data(bitmap) + ldns_rdf_size(bitmap);
-
-	/* Type Bitmap = ( Window Block # | Bitmap Length | Bitmap ) +
-	 *                 dptr[0]          dptr[1]         dptr[2:]
-	 */
-	while (dptr < dend && dptr[0] <= window) {
-
-		if (dptr[0] == window && subtype / 8 < dptr[1] &&
-				dptr + dptr[1] + 2 <= dend) {
-
-			dptr[2 + subtype / 8] &= ~(0x80 >> (subtype % 8));
-			return LDNS_STATUS_OK;
-		}
-		dptr += dptr[1] + 2; /* next window */
-	}
-	return LDNS_STATUS_TYPE_NOT_IN_BITMAP;
-}
-
-
-bool
-ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
-{
-	ldns_rdf *nsec_owner = ldns_rr_owner(nsec);
-	ldns_rdf *hash_next;
-	char *next_hash_str;
-	ldns_rdf *nsec_next = NULL;
-	ldns_status status;
-	ldns_rdf *chopped_dname;
-	bool result;
-
-	if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
-		if (ldns_rr_rdf(nsec, 0) != NULL) {
-			nsec_next = ldns_rdf_clone(ldns_rr_rdf(nsec, 0));
-		} else {
-			return false;
-		}
-	} else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
-		hash_next = ldns_nsec3_next_owner(nsec);
-		next_hash_str = ldns_rdf2str(hash_next);
-		nsec_next = ldns_dname_new_frm_str(next_hash_str);
-		LDNS_FREE(next_hash_str);
-		chopped_dname = ldns_dname_left_chop(nsec_owner);
-		status = ldns_dname_cat(nsec_next, chopped_dname);
-		ldns_rdf_deep_free(chopped_dname);
-		if (status != LDNS_STATUS_OK) {
-			printf("error catting: %s\n", ldns_get_errorstr_by_id(status));
-		}
-	} else {
-		ldns_rdf_deep_free(nsec_next);
-		return false;
-	}
-
-	/* in the case of the last nsec */
-	if(ldns_dname_compare(nsec_owner, nsec_next) > 0) {
-		result = (ldns_dname_compare(nsec_owner, name) <= 0 ||
-				ldns_dname_compare(name, nsec_next) < 0);
-	} else if(ldns_dname_compare(nsec_owner, nsec_next) < 0) {
-		result = (ldns_dname_compare(nsec_owner, name) <= 0 &&
-		          ldns_dname_compare(name, nsec_next) < 0);
-	} else {
-		result = true;
-	}
-
-	ldns_rdf_deep_free(nsec_next);
-	return result;
-}
-
-#ifdef HAVE_SSL
-/* sig may be null - if so look in the packet */
-
-ldns_status
-ldns_pkt_verify_time(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, 
-		ldns_rr_list *k, ldns_rr_list *s, 
-		time_t check_time, ldns_rr_list *good_keys)
-{
-	ldns_rr_list *rrset;
-	ldns_rr_list *sigs;
-	ldns_rr_list *sigs_covered;
-	ldns_rdf *rdf_t;
-	ldns_rr_type t_netorder;
-
-	if (!k) {
-		return LDNS_STATUS_ERR;
-		/* return LDNS_STATUS_CRYPTO_NO_DNSKEY; */
-	}
-
-	if (t == LDNS_RR_TYPE_RRSIG) {
-		/* we don't have RRSIG(RRSIG) (yet? ;-) ) */
-		return LDNS_STATUS_ERR;
-	}
-
-	if (s) {
-		/* if s is not NULL, the sigs are given to use */
-		sigs = s;
-	} else {
-		/* otherwise get them from the packet */
-		sigs = ldns_pkt_rr_list_by_name_and_type(p, o,
-				LDNS_RR_TYPE_RRSIG,
-				LDNS_SECTION_ANY_NOQUESTION);
-		if (!sigs) {
-			/* no sigs */
-			return LDNS_STATUS_ERR;
-			/* return LDNS_STATUS_CRYPTO_NO_RRSIG; */
-		}
-	}
-
-	/* rrsig are subtyped, so now we need to find the correct
-	 * sigs for the type t
-	 */
-	t_netorder = htons(t); /* rdf are in network order! */
-	/* a type identifier is a 16-bit number, so the size is 2 bytes */
-	rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, 2, &t_netorder);
-
-	sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
-	ldns_rdf_free(rdf_t);
-	if (! sigs_covered) {
-		if (! s) {
-			ldns_rr_list_deep_free(sigs);
-		}
-		return LDNS_STATUS_ERR;
-	}
-	ldns_rr_list_deep_free(sigs_covered);
-
-	rrset = ldns_pkt_rr_list_by_name_and_type(p, o, t,
-			LDNS_SECTION_ANY_NOQUESTION);
-	if (!rrset) {
-		if (! s) {
-			ldns_rr_list_deep_free(sigs);
-		}
-		return LDNS_STATUS_ERR;
-	}
-	return ldns_verify_time(rrset, sigs, k, check_time, good_keys);
-}
-
-ldns_status
-ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, 
-		ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys)
-{
-	return ldns_pkt_verify_time(p, t, o, k, s, ldns_time(NULL), good_keys);
-}
-#endif /* HAVE_SSL */
-
-ldns_status
-ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs)
-{
-	size_t i;
-	char *next_nsec_owner_str;
-	ldns_rdf *next_nsec_owner_label;
-	ldns_rdf *next_nsec_rdf;
-	ldns_status status = LDNS_STATUS_OK;
-
-	for (i = 0; i < ldns_rr_list_rr_count(nsec3_rrs); i++) {
-		if (i == ldns_rr_list_rr_count(nsec3_rrs) - 1) {
-			next_nsec_owner_label =
-				ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(nsec3_rrs,
-													  0)), 0);
-			next_nsec_owner_str = ldns_rdf2str(next_nsec_owner_label);
-			if (next_nsec_owner_str[strlen(next_nsec_owner_str) - 1]
-			    == '.') {
-				next_nsec_owner_str[strlen(next_nsec_owner_str) - 1]
-					= '\0';
-			}
-			status = ldns_str2rdf_b32_ext(&next_nsec_rdf,
-									next_nsec_owner_str);
-			if (!ldns_rr_set_rdf(ldns_rr_list_rr(nsec3_rrs, i),
-							 next_nsec_rdf, 4)) {
-				/* todo: error */
-			}
-
-			ldns_rdf_deep_free(next_nsec_owner_label);
-			LDNS_FREE(next_nsec_owner_str);
-		} else {
-			next_nsec_owner_label =
-				ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(nsec3_rrs,
-													  i + 1)),
-							  0);
-			next_nsec_owner_str = ldns_rdf2str(next_nsec_owner_label);
-			if (next_nsec_owner_str[strlen(next_nsec_owner_str) - 1]
-			    == '.') {
-				next_nsec_owner_str[strlen(next_nsec_owner_str) - 1]
-					= '\0';
-			}
-			status = ldns_str2rdf_b32_ext(&next_nsec_rdf,
-									next_nsec_owner_str);
-			ldns_rdf_deep_free(next_nsec_owner_label);
-			LDNS_FREE(next_nsec_owner_str);
-			if (!ldns_rr_set_rdf(ldns_rr_list_rr(nsec3_rrs, i),
-							 next_nsec_rdf, 4)) {
-				/* todo: error */
-			}
-		}
-	}
-	return status;
-}
-
-int
-qsort_rr_compare_nsec3(const void *a, const void *b)
-{
-	const ldns_rr *rr1 = * (const ldns_rr **) a;
-	const ldns_rr *rr2 = * (const ldns_rr **) b;
-	if (rr1 == NULL && rr2 == NULL) {
-		return 0;
-	}
-	if (rr1 == NULL) {
-		return -1;
-	}
-	if (rr2 == NULL) {
-		return 1;
-	}
-	return ldns_rdf_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2));
-}
-
-void
-ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted)
-{
-	qsort(unsorted->_rrs,
-	      ldns_rr_list_rr_count(unsorted),
-	      sizeof(ldns_rr *),
-	      qsort_rr_compare_nsec3);
-}
-
-int
-ldns_dnssec_default_add_to_signatures( ATTR_UNUSED(ldns_rr *sig)
-				     , ATTR_UNUSED(void *n)
-				     )
-{
-	return LDNS_SIGNATURE_LEAVE_ADD_NEW;
-}
-
-int
-ldns_dnssec_default_leave_signatures( ATTR_UNUSED(ldns_rr *sig)
-				    , ATTR_UNUSED(void *n)
-				    )
-{
-	return LDNS_SIGNATURE_LEAVE_NO_ADD;
-}
-
-int
-ldns_dnssec_default_delete_signatures( ATTR_UNUSED(ldns_rr *sig)
-				     , ATTR_UNUSED(void *n)
-				     )
-{
-	return LDNS_SIGNATURE_REMOVE_NO_ADD;
-}
-
-int
-ldns_dnssec_default_replace_signatures( ATTR_UNUSED(ldns_rr *sig)
-				      , ATTR_UNUSED(void *n)
-				      )
-{
-	return LDNS_SIGNATURE_REMOVE_ADD_NEW;
-}
-
-#ifdef HAVE_SSL
-ldns_rdf *
-ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
-						  const long sig_len)
-{
-	ldns_rdf *sigdata_rdf;
-	DSA_SIG *dsasig;
-	unsigned char *dsasig_data = (unsigned char*)ldns_buffer_begin(sig);
-	size_t byte_offset;
-
-	dsasig = d2i_DSA_SIG(NULL,
-					 (const unsigned char **)&dsasig_data,
-					 sig_len);
-	if (!dsasig) {
-                DSA_SIG_free(dsasig);
-		return NULL;
-	}
-
-	dsasig_data = LDNS_XMALLOC(unsigned char, 41);
-        if(!dsasig_data) {
-                DSA_SIG_free(dsasig);
-                return NULL;
-        }
-	dsasig_data[0] = 0;
-	byte_offset = (size_t) (20 - BN_num_bytes(dsasig->r));
-	if (byte_offset > 20) {
-                DSA_SIG_free(dsasig);
-                LDNS_FREE(dsasig_data);
-		return NULL;
-	}
-	memset(&dsasig_data[1], 0, byte_offset);
-	BN_bn2bin(dsasig->r, &dsasig_data[1 + byte_offset]);
-	byte_offset = (size_t) (20 - BN_num_bytes(dsasig->s));
-	if (byte_offset > 20) {
-                DSA_SIG_free(dsasig);
-                LDNS_FREE(dsasig_data);
-		return NULL;
-	}
-	memset(&dsasig_data[21], 0, byte_offset);
-	BN_bn2bin(dsasig->s, &dsasig_data[21 + byte_offset]);
-
-	sigdata_rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, 41, dsasig_data);
-        if(!sigdata_rdf) {
-                LDNS_FREE(dsasig_data);
-        }
-	DSA_SIG_free(dsasig);
-
-	return sigdata_rdf;
-}
-
-ldns_status
-ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
-						  const ldns_rdf *sig_rdf)
-{
-	/* the EVP api wants the DER encoding of the signature... */
-	BIGNUM *R, *S;
-	DSA_SIG *dsasig;
-	unsigned char *raw_sig = NULL;
-	int raw_sig_len;
-
-        if(ldns_rdf_size(sig_rdf) < 1 + 2*SHA_DIGEST_LENGTH)
-                return LDNS_STATUS_SYNTAX_RDATA_ERR;
-	/* extract the R and S field from the sig buffer */
-	R = BN_new();
-	if(!R) return LDNS_STATUS_MEM_ERR;
-	(void) BN_bin2bn((unsigned char *) ldns_rdf_data(sig_rdf) + 1,
-	                 SHA_DIGEST_LENGTH, R);
-	S = BN_new();
-	if(!S) {
-		BN_free(R);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	(void) BN_bin2bn((unsigned char *) ldns_rdf_data(sig_rdf) + 21,
-	                 SHA_DIGEST_LENGTH, S);
-
-	dsasig = DSA_SIG_new();
-	if (!dsasig) {
-		BN_free(R);
-		BN_free(S);
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	dsasig->r = R;
-	dsasig->s = S;
-
-	raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig);
-	if (raw_sig_len < 0) {
-		DSA_SIG_free(dsasig);
-		free(raw_sig);
-		return LDNS_STATUS_SSL_ERR;
-	}
-	if (ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) {
-		ldns_buffer_write(target_buffer, raw_sig, (size_t)raw_sig_len);
-	}
-
-	DSA_SIG_free(dsasig);
-	free(raw_sig);
-
-	return ldns_buffer_status(target_buffer);
-}
-
-#ifdef USE_ECDSA
-#ifndef S_SPLINT_S
-ldns_rdf *
-ldns_convert_ecdsa_rrsig_asn12rdf(const ldns_buffer *sig, const long sig_len)
-{
-        ECDSA_SIG* ecdsa_sig;
-	unsigned char *data = (unsigned char*)ldns_buffer_begin(sig);
-        ldns_rdf* rdf;
-	ecdsa_sig = d2i_ECDSA_SIG(NULL, (const unsigned char **)&data, sig_len);
-        if(!ecdsa_sig) return NULL;
-
-        /* "r | s". */
-        data = LDNS_XMALLOC(unsigned char,
-                BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s));
-        if(!data) {
-                ECDSA_SIG_free(ecdsa_sig);
-                return NULL;
-        }
-        BN_bn2bin(ecdsa_sig->r, data);
-        BN_bn2bin(ecdsa_sig->s, data+BN_num_bytes(ecdsa_sig->r));
-	rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, (size_t)(
-		BN_num_bytes(ecdsa_sig->r) + BN_num_bytes(ecdsa_sig->s)), data);
-        ECDSA_SIG_free(ecdsa_sig);
-        return rdf;
-}
-
-ldns_status
-ldns_convert_ecdsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
-        const ldns_rdf *sig_rdf)
-{
-        ECDSA_SIG* sig;
-	int raw_sig_len;
-        long bnsize = (long)ldns_rdf_size(sig_rdf) / 2;
-        /* if too short, or not even length, do not bother */
-        if(bnsize < 16 || (size_t)bnsize*2 != ldns_rdf_size(sig_rdf))
-                return LDNS_STATUS_ERR;
-        
-        /* use the raw data to parse two evenly long BIGNUMs, "r | s". */
-        sig = ECDSA_SIG_new();
-        if(!sig) return LDNS_STATUS_MEM_ERR;
-        sig->r = BN_bin2bn((const unsigned char*)ldns_rdf_data(sig_rdf),
-                bnsize, sig->r);
-        sig->s = BN_bin2bn((const unsigned char*)ldns_rdf_data(sig_rdf)+bnsize,
-                bnsize, sig->s);
-        if(!sig->r || !sig->s) {
-                ECDSA_SIG_free(sig);
-                return LDNS_STATUS_MEM_ERR;
-        }
-
-	raw_sig_len = i2d_ECDSA_SIG(sig, NULL);
-	if (ldns_buffer_reserve(target_buffer, (size_t) raw_sig_len)) {
-                unsigned char* pp = (unsigned char*)
-			ldns_buffer_current(target_buffer);
-	        raw_sig_len = i2d_ECDSA_SIG(sig, &pp);
-                ldns_buffer_skip(target_buffer, (ssize_t) raw_sig_len);
-	}
-        ECDSA_SIG_free(sig);
-
-	return ldns_buffer_status(target_buffer);
-}
-
-#endif /* S_SPLINT_S */
-#endif /* USE_ECDSA */
-#endif /* HAVE_SSL */
diff --git a/src/ldns/dnssec_sign.c b/src/ldns/dnssec_sign.c
deleted file mode 100644
index 4af882a..0000000
--- a/src/ldns/dnssec_sign.c
+++ /dev/null
@@ -1,1456 +0,0 @@
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <ldns/dnssec.h>
-#include <ldns/dnssec_sign.h>
-
-#include <strings.h>
-#include <time.h>
-
-#ifdef HAVE_SSL
-/* this entire file is rather useless when you don't have
- * crypto...
- */
-#include <openssl/ssl.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/md5.h>
-#endif /* HAVE_SSL */
-
-ldns_rr *
-ldns_create_empty_rrsig(ldns_rr_list *rrset,
-                        ldns_key *current_key)
-{
-	uint32_t orig_ttl;
-	ldns_rr_class orig_class;
-	time_t now;
-	ldns_rr *current_sig;
-	uint8_t label_count;
-	ldns_rdf *signame;
-
-	label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
-	                                                   0)));
-        /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
-        if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
-                label_count --;
-
-	current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
-
-	/* set the type on the new signature */
-	orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
-	orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
-
-	ldns_rr_set_ttl(current_sig, orig_ttl);
-	ldns_rr_set_class(current_sig, orig_class);
-	ldns_rr_set_owner(current_sig,
-			  ldns_rdf_clone(
-			       ldns_rr_owner(
-				    ldns_rr_list_rr(rrset,
-						    0))));
-
-	/* fill in what we know of the signature */
-
-	/* set the orig_ttl */
-	(void)ldns_rr_rrsig_set_origttl(
-		   current_sig,
-		   ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
-					 orig_ttl));
-	/* the signers name */
-	signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
-	ldns_dname2canonical(signame);
-	(void)ldns_rr_rrsig_set_signame(
-			current_sig,
-			signame);
-	/* label count - get it from the first rr in the rr_list */
-	(void)ldns_rr_rrsig_set_labels(
-			current_sig,
-			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
-			                     label_count));
-	/* inception, expiration */
-	now = time(NULL);
-	if (ldns_key_inception(current_key) != 0) {
-		(void)ldns_rr_rrsig_set_inception(
-				current_sig,
-				ldns_native2rdf_int32(
-				    LDNS_RDF_TYPE_TIME,
-				    ldns_key_inception(current_key)));
-	} else {
-		(void)ldns_rr_rrsig_set_inception(
-				current_sig,
-				ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
-	}
-	if (ldns_key_expiration(current_key) != 0) {
-		(void)ldns_rr_rrsig_set_expiration(
-				current_sig,
-				ldns_native2rdf_int32(
-				    LDNS_RDF_TYPE_TIME,
-				    ldns_key_expiration(current_key)));
-	} else {
-		(void)ldns_rr_rrsig_set_expiration(
-			     current_sig,
-				ldns_native2rdf_int32(
-				    LDNS_RDF_TYPE_TIME,
-				    now + LDNS_DEFAULT_EXP_TIME));
-	}
-
-	(void)ldns_rr_rrsig_set_keytag(
-		   current_sig,
-		   ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
-		                         ldns_key_keytag(current_key)));
-
-	(void)ldns_rr_rrsig_set_algorithm(
-			current_sig,
-			ldns_native2rdf_int8(
-			    LDNS_RDF_TYPE_ALG,
-			    ldns_key_algorithm(current_key)));
-
-	(void)ldns_rr_rrsig_set_typecovered(
-			current_sig,
-			ldns_native2rdf_int16(
-			    LDNS_RDF_TYPE_TYPE,
-			    ldns_rr_get_type(ldns_rr_list_rr(rrset,
-			                                     0))));
-	return current_sig;
-}
-
-#ifdef HAVE_SSL
-ldns_rdf *
-ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
-{
-	ldns_rdf *b64rdf = NULL;
-
-	switch(ldns_key_algorithm(current_key)) {
-	case LDNS_SIGN_DSA:
-	case LDNS_SIGN_DSA_NSEC3:
-		b64rdf = ldns_sign_public_evp(
-				   sign_buf,
-				   ldns_key_evp_key(current_key),
-				   EVP_dss1());
-		break;
-	case LDNS_SIGN_RSASHA1:
-	case LDNS_SIGN_RSASHA1_NSEC3:
-		b64rdf = ldns_sign_public_evp(
-				   sign_buf,
-				   ldns_key_evp_key(current_key),
-				   EVP_sha1());
-		break;
-#ifdef USE_SHA2
-	case LDNS_SIGN_RSASHA256:
-		b64rdf = ldns_sign_public_evp(
-				   sign_buf,
-				   ldns_key_evp_key(current_key),
-				   EVP_sha256());
-		break;
-	case LDNS_SIGN_RSASHA512:
-		b64rdf = ldns_sign_public_evp(
-				   sign_buf,
-				   ldns_key_evp_key(current_key),
-				   EVP_sha512());
-		break;
-#endif /* USE_SHA2 */
-#ifdef USE_GOST
-	case LDNS_SIGN_ECC_GOST:
-		b64rdf = ldns_sign_public_evp(
-				   sign_buf,
-				   ldns_key_evp_key(current_key),
-				   EVP_get_digestbyname("md_gost94"));
-		break;
-#endif /* USE_GOST */
-#ifdef USE_ECDSA
-        case LDNS_SIGN_ECDSAP256SHA256:
-       		b64rdf = ldns_sign_public_evp(
-				   sign_buf,
-				   ldns_key_evp_key(current_key),
-				   EVP_sha256());
-                break;
-        case LDNS_SIGN_ECDSAP384SHA384:
-       		b64rdf = ldns_sign_public_evp(
-				   sign_buf,
-				   ldns_key_evp_key(current_key),
-				   EVP_sha384());
-                break;
-#endif
-	case LDNS_SIGN_RSAMD5:
-		b64rdf = ldns_sign_public_evp(
-				   sign_buf,
-				   ldns_key_evp_key(current_key),
-				   EVP_md5());
-		break;
-	default:
-		/* do _you_ know this alg? */
-		printf("unknown algorithm, ");
-		printf("is the one used available on this system?\n");
-		break;
-	}
-
-	return b64rdf;
-}
-
-/**
- * use this function to sign with a public/private key alg
- * return the created signatures
- */
-ldns_rr_list *
-ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
-{
-	ldns_rr_list *signatures;
-	ldns_rr_list *rrset_clone;
-	ldns_rr *current_sig;
-	ldns_rdf *b64rdf;
-	ldns_key *current_key;
-	size_t key_count;
-	uint16_t i;
-	ldns_buffer *sign_buf;
-	ldns_rdf *new_owner;
-
-	if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
-		return NULL;
-	}
-
-	new_owner = NULL;
-
-	signatures = ldns_rr_list_new();
-
-	/* prepare a signature and add all the know data
-	 * prepare the rrset. Sign this together.  */
-	rrset_clone = ldns_rr_list_clone(rrset);
-	if (!rrset_clone) {
-		return NULL;
-	}
-
-	/* make it canonical */
-	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
-		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), 
-			ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
-		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
-	}
-	/* sort */
-	ldns_rr_list_sort(rrset_clone);
-
-	for (key_count = 0;
-		key_count < ldns_key_list_key_count(keys);
-		key_count++) {
-		if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
-			continue;
-		}
-		sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-		if (!sign_buf) {
-			ldns_rr_list_free(rrset_clone);
-			ldns_rr_list_free(signatures);
-			ldns_rdf_free(new_owner);
-			return NULL;
-		}
-		b64rdf = NULL;
-
-		current_key = ldns_key_list_key(keys, key_count);
-		/* sign all RRs with keys that have ZSKbit, !SEPbit.
-		   sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
-		if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
-			current_sig = ldns_create_empty_rrsig(rrset_clone,
-			                                      current_key);
-
-			/* right now, we have: a key, a semi-sig and an rrset. For
-			 * which we can create the sig and base64 encode that and
-			 * add that to the signature */
-
-			if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
-			    != LDNS_STATUS_OK) {
-				ldns_buffer_free(sign_buf);
-				/* ERROR */
-				ldns_rr_list_deep_free(rrset_clone);
-				ldns_rr_free(current_sig);
-				ldns_rr_list_deep_free(signatures);
-				return NULL;
-			}
-
-			/* add the rrset in sign_buf */
-			if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
-			    != LDNS_STATUS_OK) {
-				ldns_buffer_free(sign_buf);
-				ldns_rr_list_deep_free(rrset_clone);
-				ldns_rr_free(current_sig);
-				ldns_rr_list_deep_free(signatures);
-				return NULL;
-			}
-
-			b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
-
-			if (!b64rdf) {
-				/* signing went wrong */
-				ldns_rr_list_deep_free(rrset_clone);
-				ldns_rr_free(current_sig);
-				ldns_rr_list_deep_free(signatures);
-				return NULL;
-			}
-
-			ldns_rr_rrsig_set_sig(current_sig, b64rdf);
-
-			/* push the signature to the signatures list */
-			ldns_rr_list_push_rr(signatures, current_sig);
-		}
-		ldns_buffer_free(sign_buf); /* restart for the next key */
-	}
-	ldns_rr_list_deep_free(rrset_clone);
-
-	return signatures;
-}
-
-/**
- * Sign data with DSA
- *
- * \param[in] to_sign The ldns_buffer containing raw data that is
- *                    to be signed
- * \param[in] key The DSA key structure to sign with
- * \return ldns_rdf for the RRSIG ldns_rr
- */
-ldns_rdf *
-ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
-{
-	unsigned char *sha1_hash;
-	ldns_rdf *sigdata_rdf;
-	ldns_buffer *b64sig;
-
-	DSA_SIG *sig;
-	uint8_t *data;
-	size_t pad;
-
-	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	if (!b64sig) {
-		return NULL;
-	}
-
-	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
-				  ldns_buffer_position(to_sign), NULL);
-	if (!sha1_hash) {
-		ldns_buffer_free(b64sig);
-		return NULL;
-	}
-
-	sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
-        if(!sig) {
-		ldns_buffer_free(b64sig);
-		return NULL;
-        }
-
-	data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
-        if(!data) {
-		ldns_buffer_free(b64sig);
-                DSA_SIG_free(sig);
-		return NULL;
-        }
-
-	data[0] = 1;
-	pad = 20 - (size_t) BN_num_bytes(sig->r);
-	if (pad > 0) {
-		memset(data + 1, 0, pad);
-	}
-	BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
-
-	pad = 20 - (size_t) BN_num_bytes(sig->s);
-	if (pad > 0) {
-		memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
-	}
-	BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
-
-	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
-								 1 + 2 * SHA_DIGEST_LENGTH,
-								 data);
-
-	ldns_buffer_free(b64sig);
-	LDNS_FREE(data);
-        DSA_SIG_free(sig);
-
-	return sigdata_rdf;
-}
-
-#ifdef USE_ECDSA
-#ifndef S_SPLINT_S
-static int
-ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
-{
-        EC_KEY* ec;
-        const EC_GROUP* g;
-        if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
-                return 0;
-        ec = EVP_PKEY_get1_EC_KEY(pkey);
-        g = EC_KEY_get0_group(ec);
-        if(!g) {
-                EC_KEY_free(ec);
-                return 0;
-        }
-        if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
-                EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
-                EC_GROUP_get_curve_name(g) == NID_secp384r1) {
-                EC_KEY_free(ec);
-                return 1;
-        }
-        /* downref the eckey, the original is still inside the pkey */
-        EC_KEY_free(ec);
-        return 0;
-}
-#endif /* splint */
-#endif /* USE_ECDSA */
-
-ldns_rdf *
-ldns_sign_public_evp(ldns_buffer *to_sign,
-				 EVP_PKEY *key,
-				 const EVP_MD *digest_type)
-{
-	unsigned int siglen;
-	ldns_rdf *sigdata_rdf;
-	ldns_buffer *b64sig;
-	EVP_MD_CTX ctx;
-	const EVP_MD *md_type;
-	int r;
-
-	siglen = 0;
-	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	if (!b64sig) {
-		return NULL;
-	}
-
-	/* initializes a signing context */
-	md_type = digest_type;
-	if(!md_type) {
-		/* unknown message difest */
-		ldns_buffer_free(b64sig);
-		return NULL;
-	}
-
-	EVP_MD_CTX_init(&ctx);
-	r = EVP_SignInit(&ctx, md_type);
-	if(r == 1) {
-		r = EVP_SignUpdate(&ctx, (unsigned char*)
-					    ldns_buffer_begin(to_sign),
-					    ldns_buffer_position(to_sign));
-	} else {
-		ldns_buffer_free(b64sig);
-		return NULL;
-	}
-	if(r == 1) {
-		r = EVP_SignFinal(&ctx, (unsigned char*)
-					   ldns_buffer_begin(b64sig), &siglen, key);
-	} else {
-		ldns_buffer_free(b64sig);
-		return NULL;
-	}
-	if(r != 1) {
-		ldns_buffer_free(b64sig);
-		return NULL;
-	}
-
-	/* unfortunately, OpenSSL output is differenct from DNS DSA format */
-#ifndef S_SPLINT_S
-	if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
-		sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
-#ifdef USE_ECDSA
-        } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
-                ldns_pkey_is_ecdsa(key)) {
-                sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
-#endif
-	} else {
-		/* ok output for other types is the same */
-		sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
-									 ldns_buffer_begin(b64sig));
-	}
-#endif /* splint */
-	ldns_buffer_free(b64sig);
-	EVP_MD_CTX_cleanup(&ctx);
-	return sigdata_rdf;
-}
-
-ldns_rdf *
-ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
-{
-	unsigned char *sha1_hash;
-	unsigned int siglen;
-	ldns_rdf *sigdata_rdf;
-	ldns_buffer *b64sig;
-	int result;
-
-	siglen = 0;
-	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	if (!b64sig) {
-		return NULL;
-	}
-
-	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
-				  ldns_buffer_position(to_sign), NULL);
-	if (!sha1_hash) {
-		ldns_buffer_free(b64sig);
-		return NULL;
-	}
-
-	result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
-				   (unsigned char*)ldns_buffer_begin(b64sig),
-				   &siglen, key);
-	if (result != 1) {
-		ldns_buffer_free(b64sig);
-		return NULL;
-	}
-
-	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 
-								 ldns_buffer_begin(b64sig));
-	ldns_buffer_free(b64sig); /* can't free this buffer ?? */
-	return sigdata_rdf;
-}
-
-ldns_rdf *
-ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
-{
-	unsigned char *md5_hash;
-	unsigned int siglen;
-	ldns_rdf *sigdata_rdf;
-	ldns_buffer *b64sig;
-
-	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	if (!b64sig) {
-		return NULL;
-	}
-
-	md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
-				ldns_buffer_position(to_sign), NULL);
-	if (!md5_hash) {
-		ldns_buffer_free(b64sig);
-		return NULL;
-	}
-
-	RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
-		    (unsigned char*)ldns_buffer_begin(b64sig),
-		    &siglen, key);
-
-	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
-								 ldns_buffer_begin(b64sig));
-	ldns_buffer_free(b64sig);
-	return sigdata_rdf;
-}
-#endif /* HAVE_SSL */
-
-/**
- * Pushes all rrs from the rrsets of type A and AAAA on gluelist.
- */
-static ldns_status
-ldns_dnssec_addresses_on_glue_list(
-		ldns_dnssec_rrsets *cur_rrset,
-		ldns_rr_list *glue_list)
-{
-	ldns_dnssec_rrs *cur_rrs;
-	while (cur_rrset) {
-		if (cur_rrset->type == LDNS_RR_TYPE_A 
-				|| cur_rrset->type == LDNS_RR_TYPE_AAAA) {
-			for (cur_rrs = cur_rrset->rrs; 
-					cur_rrs; 
-					cur_rrs = cur_rrs->next) {
-				if (cur_rrs->rr) {
-					if (!ldns_rr_list_push_rr(glue_list, 
-							cur_rrs->rr)) {
-						return LDNS_STATUS_MEM_ERR; 
-						/* ldns_rr_list_push_rr()
-						 * returns false when unable
-						 * to increase the capacity
-						 * of the ldsn_rr_list
-						 */
-					}
-				}
-			}
-		}
-		cur_rrset = cur_rrset->next;
-	}
-	return LDNS_STATUS_OK;
-}
-
-/**
- * Marks the names in the zone that are occluded. Those names will be skipped
- * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
- * function. But watch out! Names that are partially occluded (like glue with
- * the same name as the delegation) will not be marked and should specifically 
- * be taken into account separately.
- *
- * When glue_list is given (not NULL), in the process of marking the names, all
- * glue resource records will be pushed to that list, even glue at delegation names.
- *
- * \param[in] zone the zone in which to mark the names
- * \param[in] glue_list the list to which to push the glue rrs
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status
-ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 
-	ldns_rr_list *glue_list)
-{
-	ldns_rbnode_t    *node;
-	ldns_dnssec_name *name;
-	ldns_rdf         *owner;
-	ldns_rdf         *cut = NULL; /* keeps track of zone cuts */
-	/* When the cut is caused by a delegation, below_delegation will be 1.
-	 * When caused by a DNAME, below_delegation will be 0.
-	 */
-	int below_delegation = -1; /* init suppresses comiler warning */
-	ldns_status s;
-
-	if (!zone || !zone->names) {
-		return LDNS_STATUS_NULL;
-	}
-	for (node = ldns_rbtree_first(zone->names); 
-			node != LDNS_RBTREE_NULL; 
-			node = ldns_rbtree_next(node)) {
-		name = (ldns_dnssec_name *) node->data;
-		owner = ldns_dnssec_name_name(name);
-
-		if (cut) { 
-			/* The previous node was a zone cut, or a subdomain
-			 * below a zone cut. Is this node (still) a subdomain
-			 * below the cut? Then the name is occluded. Unless
-			 * the name contains a SOA, after which we are 
-			 * authoritative again.
-			 *
-			 * FIXME! If there are labels in between the SOA and
-			 * the cut, going from the authoritative space (below
-			 * the SOA) up into occluded space again, will not be
-			 * detected with the contruct below!
-			 */
-			if (ldns_dname_is_subdomain(owner, cut) &&
-					!ldns_dnssec_rrsets_contains_type(
-					name->rrsets, LDNS_RR_TYPE_SOA)) {
-
-				if (below_delegation && glue_list) {
-					s = ldns_dnssec_addresses_on_glue_list(
-						name->rrsets, glue_list);
-					if (s != LDNS_STATUS_OK) {
-						return s;
-					}
-				}
-				name->is_glue = true; /* Mark occluded name! */
-				continue;
-			} else {
-				cut = NULL;
-			}
-		}
-
-		/* The node is not below a zone cut. Is it a zone cut itself?
-		 * Everything below a SOA is authoritative of course; Except
-		 * when the name also contains a DNAME :).
-		 */
-		if (ldns_dnssec_rrsets_contains_type(
-				name->rrsets, LDNS_RR_TYPE_NS)
-			    && !ldns_dnssec_rrsets_contains_type(
-				name->rrsets, LDNS_RR_TYPE_SOA)) {
-			cut = owner;
-			below_delegation = 1;
-			if (glue_list) { /* record glue on the zone cut */
-				s = ldns_dnssec_addresses_on_glue_list(
-					name->rrsets, glue_list);
-				if (s != LDNS_STATUS_OK) {
-					return s;
-				}
-			}
-		} else if (ldns_dnssec_rrsets_contains_type(
-				name->rrsets, LDNS_RR_TYPE_DNAME)) {
-			cut = owner;
-			below_delegation = 0;
-		}
-	}
-	return LDNS_STATUS_OK;
-}
-
-/**
- * Marks the names in the zone that are occluded. Those names will be skipped
- * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
- * function. But watch out! Names that are partially occluded (like glue with
- * the same name as the delegation) will not be marked and should specifically 
- * be taken into account separately.
- *
- * \param[in] zone the zone in which to mark the names
- * \return LDNS_STATUS_OK on success, an error code otherwise
- */
-ldns_status
-ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
-{
-	return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
-}
-
-ldns_rbnode_t *
-ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
-{
-	ldns_rbnode_t *next_node = NULL;
-	ldns_dnssec_name *next_name = NULL;
-	bool done = false;
-
-	if (node == LDNS_RBTREE_NULL) {
-		return NULL;
-	}
-	next_node = node;
-	while (!done) {
-		if (next_node == LDNS_RBTREE_NULL) {
-			return NULL;
-		} else {
-			next_name = (ldns_dnssec_name *)next_node->data;
-			if (!next_name->is_glue) {
-				done = true;
-			} else {
-				next_node = ldns_rbtree_next(next_node);
-			}
-		}
-	}
-	return next_node;
-}
-
-ldns_status
-ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
-                              ldns_rr_list *new_rrs)
-{
-
-	ldns_rbnode_t *first_node, *cur_node, *next_node;
-	ldns_dnssec_name *cur_name, *next_name;
-	ldns_rr *nsec_rr;
-	uint32_t nsec_ttl;
-	ldns_dnssec_rrsets *soa;
-
-	/* the TTL of NSEC rrs should be set to the minimum TTL of
-	 * the zone SOA (RFC4035 Section 2.3)
-	 */
-	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
-
-	/* did the caller actually set it? if not,
-	 * fall back to default ttl
-	 */
-	if (soa && soa->rrs && soa->rrs->rr
-			&& (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
-		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
-	} else {
-		nsec_ttl = LDNS_DEFAULT_TTL;
-	}
-
-	first_node = ldns_dnssec_name_node_next_nonglue(
-			       ldns_rbtree_first(zone->names));
-	cur_node = first_node;
-	if (cur_node) {
-		next_node = ldns_dnssec_name_node_next_nonglue(
-			           ldns_rbtree_next(cur_node));
-	} else {
-		next_node = NULL;
-	}
-
-	while (cur_node && next_node) {
-		cur_name = (ldns_dnssec_name *)cur_node->data;
-		next_name = (ldns_dnssec_name *)next_node->data;
-		nsec_rr = ldns_dnssec_create_nsec(cur_name,
-		                                  next_name,
-		                                  LDNS_RR_TYPE_NSEC);
-		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
-		if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
-			ldns_rr_free(nsec_rr);
-			return LDNS_STATUS_ERR;
-		}
-		ldns_rr_list_push_rr(new_rrs, nsec_rr);
-		cur_node = next_node;
-		if (cur_node) {
-			next_node = ldns_dnssec_name_node_next_nonglue(
-                               ldns_rbtree_next(cur_node));
-		}
-	}
-
-	if (cur_node && !next_node) {
-		cur_name = (ldns_dnssec_name *)cur_node->data;
-		next_name = (ldns_dnssec_name *)first_node->data;
-		nsec_rr = ldns_dnssec_create_nsec(cur_name,
-		                                  next_name,
-		                                  LDNS_RR_TYPE_NSEC);
-		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
-		if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
-			ldns_rr_free(nsec_rr);
-			return LDNS_STATUS_ERR;
-		}
-		ldns_rr_list_push_rr(new_rrs, nsec_rr);
-	} else {
-		printf("error\n");
-	}
-
-	return LDNS_STATUS_OK;
-}
-
-#ifdef HAVE_SSL
-static void
-ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
-	(void) arg;
-	LDNS_FREE(node);
-}
-
-static ldns_status
-ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
-		ldns_rr_list *new_rrs,
-		uint8_t algorithm,
-		uint8_t flags,
-		uint16_t iterations,
-		uint8_t salt_length,
-		uint8_t *salt,
-		ldns_rbtree_t **map)
-{
-	ldns_rbnode_t *first_name_node;
-	ldns_rbnode_t *current_name_node;
-	ldns_dnssec_name *current_name;
-	ldns_status result = LDNS_STATUS_OK;
-	ldns_rr *nsec_rr;
-	ldns_rr_list *nsec3_list;
-	uint32_t nsec_ttl;
-	ldns_dnssec_rrsets *soa;
-	ldns_rbnode_t *hashmap_node;
-
-	if (!zone || !new_rrs || !zone->names) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* the TTL of NSEC rrs should be set to the minimum TTL of
-	 * the zone SOA (RFC4035 Section 2.3)
-	 */
-	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
-
-	/* did the caller actually set it? if not,
-	 * fall back to default ttl
-	 */
-	if (soa && soa->rrs && soa->rrs->rr
-			&& ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
-		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
-	} else {
-		nsec_ttl = LDNS_DEFAULT_TTL;
-	}
-
-	if (zone->hashed_names) {
-		ldns_traverse_postorder(zone->hashed_names,
-				ldns_hashed_names_node_free, NULL);
-		LDNS_FREE(zone->hashed_names);
-	}
-	zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
-	if (zone->hashed_names && map) {
-		*map = zone->hashed_names;
-	}
-
-	first_name_node = ldns_dnssec_name_node_next_nonglue(
-					  ldns_rbtree_first(zone->names));
-
-	current_name_node = first_name_node;
-
-	while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
-			result == LDNS_STATUS_OK) {
-
-		current_name = (ldns_dnssec_name *) current_name_node->data;
-		nsec_rr = ldns_dnssec_create_nsec3(current_name,
-		                                   NULL,
-		                                   zone->soa->name,
-		                                   algorithm,
-		                                   flags,
-		                                   iterations,
-		                                   salt_length,
-		                                   salt);
-		/* by default, our nsec based generator adds rrsigs
-		 * remove the bitmap for empty nonterminals */
-		if (!current_name->rrsets) {
-			ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
-		}
-		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
-		result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
-		ldns_rr_list_push_rr(new_rrs, nsec_rr);
-		if (ldns_rr_owner(nsec_rr)) {
-			hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
-			if (hashmap_node == NULL) {
-				return LDNS_STATUS_MEM_ERR;
-			}
-			current_name->hashed_name = 
-				ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
-
-			if (current_name->hashed_name == NULL) {
-				LDNS_FREE(hashmap_node);
-				return LDNS_STATUS_MEM_ERR;
-			}
-			hashmap_node->key  = current_name->hashed_name;
-			hashmap_node->data = current_name;
-
-			if (! ldns_rbtree_insert(zone->hashed_names
-						, hashmap_node)) {
-				LDNS_FREE(hashmap_node);
-			}
-		}
-		current_name_node = ldns_dnssec_name_node_next_nonglue(
-		                   ldns_rbtree_next(current_name_node));
-	}
-	if (result != LDNS_STATUS_OK) {
-		return result;
-	}
-
-	/* Make sorted list of nsec3s (via zone->hashed_names)
-	 */
-	nsec3_list = ldns_rr_list_new();
-	if (nsec3_list == NULL) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	for ( hashmap_node  = ldns_rbtree_first(zone->hashed_names)
-	    ; hashmap_node != LDNS_RBTREE_NULL
-	    ; hashmap_node  = ldns_rbtree_next(hashmap_node)
-	    ) {
-		current_name = (ldns_dnssec_name *) hashmap_node->data;
-		nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
-		if (nsec_rr) {
-			ldns_rr_list_push_rr(nsec3_list, nsec_rr);
-		}
-	}
-	result = ldns_dnssec_chain_nsec3_list(nsec3_list);
-	ldns_rr_list_free(nsec3_list);
-
-	return result;
-}
-
-ldns_status
-ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
-		ldns_rr_list *new_rrs,
-		uint8_t algorithm,
-		uint8_t flags,
-		uint16_t iterations,
-		uint8_t salt_length,
-		uint8_t *salt)
-{
-	return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
-		       	flags, iterations, salt_length, salt, NULL);
-
-}
-#endif /* HAVE_SSL */
-
-ldns_dnssec_rrs *
-ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
-			     , ATTR_UNUSED(ldns_key_list *key_list)
-			     , int (*func)(ldns_rr *, void *)
-			     , void *arg
-			     )
-{
-	ldns_dnssec_rrs *base_rrs = signatures;
-	ldns_dnssec_rrs *cur_rr = base_rrs;
-	ldns_dnssec_rrs *prev_rr = NULL;
-	ldns_dnssec_rrs *next_rr;
-
-	uint16_t keytag;
-	size_t i;
-
-	if (!cur_rr) {
-		switch(func(NULL, arg)) {
-		case LDNS_SIGNATURE_LEAVE_ADD_NEW:
-		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
-		break;
-		case LDNS_SIGNATURE_LEAVE_NO_ADD:
-		case LDNS_SIGNATURE_REMOVE_NO_ADD:
-		ldns_key_list_set_use(key_list, false);
-		break;
-		default:
-#ifdef STDERR_MSGS
-			fprintf(stderr, "[XX] unknown return value from callback\n");
-#endif
-			break;
-		}
-		return NULL;
-	}
-	(void)func(cur_rr->rr, arg);
-
-	while (cur_rr) {
-		next_rr = cur_rr->next;
-
-		switch (func(cur_rr->rr, arg)) {
-		case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
-			prev_rr = cur_rr;
-			break;
-		case LDNS_SIGNATURE_LEAVE_NO_ADD:
-			keytag = ldns_rdf2native_int16(
-					   ldns_rr_rrsig_keytag(cur_rr->rr));
-			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
-				if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
-				    keytag) {
-					ldns_key_set_use(ldns_key_list_key(key_list, i),
-								  false);
-				}
-			}
-			prev_rr = cur_rr;
-			break;
-		case LDNS_SIGNATURE_REMOVE_NO_ADD:
-			keytag = ldns_rdf2native_int16(
-					   ldns_rr_rrsig_keytag(cur_rr->rr));
-			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
-				if (ldns_key_keytag(ldns_key_list_key(key_list, i))
-				    == keytag) {
-					ldns_key_set_use(ldns_key_list_key(key_list, i),
-								  false);
-				}
-			}
-			if (prev_rr) {
-				prev_rr->next = next_rr;
-			} else {
-				base_rrs = next_rr;
-			}
-			LDNS_FREE(cur_rr);
-			break;
-		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
-			if (prev_rr) {
-				prev_rr->next = next_rr;
-			} else {
-				base_rrs = next_rr;
-			}
-			LDNS_FREE(cur_rr);
-			break;
-		default:
-#ifdef STDERR_MSGS
-			fprintf(stderr, "[XX] unknown return value from callback\n");
-#endif
-			break;
-		}
-		cur_rr = next_rr;
-	}
-
-	return base_rrs;
-}
-
-#ifdef HAVE_SSL
-ldns_status
-ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
-                               ldns_rr_list *new_rrs,
-                               ldns_key_list *key_list,
-                               int (*func)(ldns_rr *, void*),
-                               void *arg)
-{
-	return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
-		func, arg, 0);
-}
-
-/** If there are KSKs use only them and mark ZSKs unused */
-static void
-ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
-{
-	int saw_ksk = 0;
-	size_t i;
-	for(i=0; i<ldns_key_list_key_count(key_list); i++)
-		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
-			saw_ksk = 1;
-			break;
-		}
-	if(!saw_ksk)
-		return;
-	for(i=0; i<ldns_key_list_key_count(key_list); i++)
-		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
-			ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
-}
-
-/** If there are no ZSKs use KSK as ZSK */
-static void
-ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
-{
-	int saw_zsk = 0;
-	size_t i;
-	for(i=0; i<ldns_key_list_key_count(key_list); i++)
-		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
-			saw_zsk = 1;
-			break;
-		}
-	if(!saw_zsk)
-		return;
-	/* else filter all KSKs */
-	for(i=0; i<ldns_key_list_key_count(key_list); i++)
-		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
-			ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
-}
-
-ldns_status
-ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
-				  , ldns_rr_list *new_rrs
-				  , ldns_key_list *key_list
-				  , int (*func)(ldns_rr *, void*)
-				  , void *arg
-				  , int flags
-				  )
-{
-	ldns_status result = LDNS_STATUS_OK;
-
-	ldns_rbnode_t *cur_node;
-	ldns_rr_list *rr_list;
-
-	ldns_dnssec_name *cur_name;
-	ldns_dnssec_rrsets *cur_rrset;
-	ldns_dnssec_rrs *cur_rr;
-
-	ldns_rr_list *siglist;
-
-	size_t i;
-
-	int on_delegation_point = 0; /* handle partially occluded names */
-
-	ldns_rr_list *pubkey_list = ldns_rr_list_new();
-	for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
-		ldns_rr_list_push_rr( pubkey_list
-				    , ldns_key2rr(ldns_key_list_key(
-							key_list, i))
-				    );
-	}
-	/* TODO: callback to see is list should be signed */
-	/* TODO: remove 'old' signatures from signature list */
-	cur_node = ldns_rbtree_first(zone->names);
-	while (cur_node != LDNS_RBTREE_NULL) {
-		cur_name = (ldns_dnssec_name *) cur_node->data;
-
-		if (!cur_name->is_glue) {
-			on_delegation_point = ldns_dnssec_rrsets_contains_type(
-					cur_name->rrsets, LDNS_RR_TYPE_NS)
-				&& !ldns_dnssec_rrsets_contains_type(
-					cur_name->rrsets, LDNS_RR_TYPE_SOA);
-			cur_rrset = cur_name->rrsets;
-			while (cur_rrset) {
-				/* reset keys to use */
-				ldns_key_list_set_use(key_list, true);
-
-				/* walk through old sigs, remove the old,
-				   and mark which keys (not) to use) */
-				cur_rrset->signatures =
-					ldns_dnssec_remove_signatures(cur_rrset->signatures,
-											key_list,
-											func,
-											arg);
-				if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
-					cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
-					ldns_key_list_filter_for_dnskey(key_list);
-
-				if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
-					ldns_key_list_filter_for_non_dnskey(key_list);
-
-				/* TODO: just set count to zero? */
-				rr_list = ldns_rr_list_new();
-
-				cur_rr = cur_rrset->rrs;
-				while (cur_rr) {
-					ldns_rr_list_push_rr(rr_list, cur_rr->rr);
-					cur_rr = cur_rr->next;
-				}
-
-				/* only sign non-delegation RRsets */
-				/* (glue should have been marked earlier, 
-				 *  except on the delegation points itself) */
-				if (!on_delegation_point ||
-						ldns_rr_list_type(rr_list) 
-							== LDNS_RR_TYPE_DS ||
-						ldns_rr_list_type(rr_list) 
-							== LDNS_RR_TYPE_NSEC ||
-						ldns_rr_list_type(rr_list) 
-							== LDNS_RR_TYPE_NSEC3) {
-					siglist = ldns_sign_public(rr_list, key_list);
-					for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
-						if (cur_rrset->signatures) {
-							result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
-											   ldns_rr_list_rr(siglist,
-														    i));
-						} else {
-							cur_rrset->signatures = ldns_dnssec_rrs_new();
-							cur_rrset->signatures->rr =
-								ldns_rr_list_rr(siglist, i);
-						}
-						if (new_rrs) {
-							ldns_rr_list_push_rr(new_rrs,
-												 ldns_rr_list_rr(siglist,
-															  i));
-						}
-					}
-					ldns_rr_list_free(siglist);
-				}
-
-				ldns_rr_list_free(rr_list);
-
-				cur_rrset = cur_rrset->next;
-			}
-
-			/* sign the nsec */
-			ldns_key_list_set_use(key_list, true);
-			cur_name->nsec_signatures =
-				ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
-										key_list,
-										func,
-										arg);
-			ldns_key_list_filter_for_non_dnskey(key_list);
-
-			rr_list = ldns_rr_list_new();
-			ldns_rr_list_push_rr(rr_list, cur_name->nsec);
-			siglist = ldns_sign_public(rr_list, key_list);
-
-			for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
-				if (cur_name->nsec_signatures) {
-					result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
-									   ldns_rr_list_rr(siglist, i));
-				} else {
-					cur_name->nsec_signatures = ldns_dnssec_rrs_new();
-					cur_name->nsec_signatures->rr =
-						ldns_rr_list_rr(siglist, i);
-				}
-				if (new_rrs) {
-					ldns_rr_list_push_rr(new_rrs,
-								 ldns_rr_list_rr(siglist, i));
-				}
-			}
-
-			ldns_rr_list_free(siglist);
-			ldns_rr_list_free(rr_list);
-		}
-		cur_node = ldns_rbtree_next(cur_node);
-	}
-
-	ldns_rr_list_deep_free(pubkey_list);
-	return result;
-}
-
-ldns_status
-ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
-				  ldns_rr_list *new_rrs,
-				  ldns_key_list *key_list,
-				  int (*func)(ldns_rr *, void *),
-				  void *arg)
-{
-	return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
-}
-
-ldns_status
-ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
-				  ldns_rr_list *new_rrs,
-				  ldns_key_list *key_list,
-				  int (*func)(ldns_rr *, void *),
-				  void *arg,
-				  int flags)
-{
-	ldns_status result = LDNS_STATUS_OK;
-
-	if (!zone || !new_rrs || !key_list) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* zone is already sorted */
-	result = ldns_dnssec_zone_mark_glue(zone);
-	if (result != LDNS_STATUS_OK) {
-		return result;
-	}
-
-	/* check whether we need to add nsecs */
-	if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
-		result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
-		if (result != LDNS_STATUS_OK) {
-			return result;
-		}
-	}
-
-	result = ldns_dnssec_zone_create_rrsigs_flg(zone,
-					new_rrs,
-					key_list,
-					func,
-					arg,
-					flags);
-
-	return result;
-}
-
-ldns_status
-ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
-					   ldns_rr_list *new_rrs,
-					   ldns_key_list *key_list,
-					   int (*func)(ldns_rr *, void *),
-					   void *arg,
-					   uint8_t algorithm,
-					   uint8_t flags,
-					   uint16_t iterations,
-					   uint8_t salt_length,
-					   uint8_t *salt)
-{
-	return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
-		func, arg, algorithm, flags, iterations, salt_length, salt, 0,
-	       	NULL);
-}
-
-ldns_status
-ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
-		ldns_rr_list *new_rrs,
-		ldns_key_list *key_list,
-		int (*func)(ldns_rr *, void *),
-		void *arg,
-		uint8_t algorithm,
-		uint8_t flags,
-		uint16_t iterations,
-		uint8_t salt_length,
-		uint8_t *salt,
-		int signflags,
-		ldns_rbtree_t **map)
-{
-	ldns_rr *nsec3, *nsec3param;
-	ldns_status result = LDNS_STATUS_OK;
-
-	/* zone is already sorted */
-	result = ldns_dnssec_zone_mark_glue(zone);
-	if (result != LDNS_STATUS_OK) {
-		return result;
-	}
-
-	/* TODO if there are already nsec3s presents and their
-	 * parameters are the same as these, we don't have to recreate
-	 */
-	if (zone->names) {
-		/* add empty nonterminals */
-		result = ldns_dnssec_zone_add_empty_nonterminals(zone);
-		if (result != LDNS_STATUS_OK) {
-			return result;
-		}
-
-		nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
-		if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
-			/* no need to recreate */
-		} else {
-			if (!ldns_dnssec_zone_find_rrset(zone,
-									   zone->soa->name,
-									   LDNS_RR_TYPE_NSEC3PARAM)) {
-				/* create and add the nsec3param rr */
-				nsec3param =
-					ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
-				ldns_rr_set_owner(nsec3param,
-							   ldns_rdf_clone(zone->soa->name));
-				ldns_nsec3_add_param_rdfs(nsec3param,
-									 algorithm,
-									 flags,
-									 iterations,
-									 salt_length,
-									 salt);
-				/* always set bit 7 of the flags to zero, according to
-				 * rfc5155 section 11. The bits are counted from right to left,
-				 * so bit 7 in rfc5155 is bit 0 in ldns */
-				ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
-				result = ldns_dnssec_zone_add_rr(zone, nsec3param);
-				if (result != LDNS_STATUS_OK) {
-					return result;
-				}
-				ldns_rr_list_push_rr(new_rrs, nsec3param);
-			}
-			result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
-											new_rrs,
-											algorithm,
-											flags,
-											iterations,
-											salt_length,
-											salt,
-											map);
-			if (result != LDNS_STATUS_OK) {
-				return result;
-			}
-		}
-
-		result = ldns_dnssec_zone_create_rrsigs_flg(zone,
-						new_rrs,
-						key_list,
-						func,
-						arg,
-						signflags);
-	}
-
-	return result;
-}
-
-ldns_status
-ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
-		ldns_rr_list *new_rrs,
-		ldns_key_list *key_list,
-		int (*func)(ldns_rr *, void *),
-		void *arg,
-		uint8_t algorithm,
-		uint8_t flags,
-		uint16_t iterations,
-		uint8_t salt_length,
-		uint8_t *salt,
-		int signflags)
-{
-	return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
-		func, arg, algorithm, flags, iterations, salt_length, salt,
-		signflags, NULL);
-}
-
-ldns_zone *
-ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
-{
-	ldns_dnssec_zone *dnssec_zone;
-	ldns_zone *signed_zone;
-	ldns_rr_list *new_rrs;
-	size_t i;
-
-	signed_zone = ldns_zone_new();
-	dnssec_zone = ldns_dnssec_zone_new();
-
-	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
-	ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
-
-	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
-		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
-								 ldns_rr_list_rr(ldns_zone_rrs(zone),
-											  i));
-		ldns_zone_push_rr(signed_zone,
-					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
-											   i)));
-	}
-
-	new_rrs = ldns_rr_list_new();
-	(void) ldns_dnssec_zone_sign(dnssec_zone,
-						    new_rrs,
-						    key_list,
-						    ldns_dnssec_default_replace_signatures,
-						    NULL);
-
-    	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
-		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
-						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
-	}
-
-	ldns_rr_list_deep_free(new_rrs);
-	ldns_dnssec_zone_free(dnssec_zone);
-
-	return signed_zone;
-}
-
-ldns_zone *
-ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt)
-{
-	ldns_dnssec_zone *dnssec_zone;
-	ldns_zone *signed_zone;
-	ldns_rr_list *new_rrs;
-	size_t i;
-
-	signed_zone = ldns_zone_new();
-	dnssec_zone = ldns_dnssec_zone_new();
-
-	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
-	ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
-
-	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
-		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
-								 ldns_rr_list_rr(ldns_zone_rrs(zone),
-											  i));
-		ldns_zone_push_rr(signed_zone, 
-					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
-											   i)));
-	}
-
-	new_rrs = ldns_rr_list_new();
-	(void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
-								new_rrs,
-								key_list,
-								ldns_dnssec_default_replace_signatures,
-								NULL,
-								algorithm,
-								flags,
-								iterations,
-								salt_length,
-								salt);
-
-    	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
-		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
-						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
-	}
-
-	ldns_rr_list_deep_free(new_rrs);
-	ldns_dnssec_zone_free(dnssec_zone);
-
-	return signed_zone;
-}
-#endif /* HAVE_SSL */
-
-
diff --git a/src/ldns/dnssec_verify.c b/src/ldns/dnssec_verify.c
deleted file mode 100644
index 1af6635..0000000
--- a/src/ldns/dnssec_verify.c
+++ /dev/null
@@ -1,2684 +0,0 @@
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <strings.h>
-#include <time.h>
-
-#ifdef HAVE_SSL
-/* this entire file is rather useless when you don't have
- * crypto...
- */
-#include <openssl/ssl.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/md5.h>
-
-ldns_dnssec_data_chain *
-ldns_dnssec_data_chain_new(void)
-{
-	ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
-        if(!nc) return NULL;
-	/* 
-	 * not needed anymore because CALLOC initalizes everything to zero.
-
-	nc->rrset = NULL;
-	nc->parent_type = 0;
-	nc->parent = NULL;
-	nc->signatures = NULL;
-	nc->packet_rcode = 0;
-	nc->packet_qtype = 0;
-	nc->packet_nodata = false;
-
-	 */
-	return nc;
-}
-
-void
-ldns_dnssec_data_chain_free(ldns_dnssec_data_chain *chain)
-{
-	LDNS_FREE(chain);
-}
-
-void
-ldns_dnssec_data_chain_deep_free(ldns_dnssec_data_chain *chain)
-{
-	ldns_rr_list_deep_free(chain->rrset);
-	ldns_rr_list_deep_free(chain->signatures);
-	if (chain->parent) {
-		ldns_dnssec_data_chain_deep_free(chain->parent);
-	}
-	LDNS_FREE(chain);
-}
-
-void
-ldns_dnssec_data_chain_print_fmt(FILE *out, const ldns_output_format *fmt,
-		const ldns_dnssec_data_chain *chain)
-{
-	ldns_lookup_table *rcode;
-	const ldns_rr_descriptor *rr_descriptor;
-	if (chain) {
-		ldns_dnssec_data_chain_print_fmt(out, fmt, chain->parent);
-		if (ldns_rr_list_rr_count(chain->rrset) > 0) {
-			rcode = ldns_lookup_by_id(ldns_rcodes,
-								 (int) chain->packet_rcode);
-			if (rcode) {
-				fprintf(out, ";; rcode: %s\n", rcode->name);
-			}
-
-			rr_descriptor = ldns_rr_descript(chain->packet_qtype);
-			if (rr_descriptor && rr_descriptor->_name) {
-				fprintf(out, ";; qtype: %s\n", rr_descriptor->_name);
-			} else if (chain->packet_qtype != 0) {
-				fprintf(out, "TYPE%u", 
-					   chain->packet_qtype);
-			}
-			if (chain->packet_nodata) {
-				fprintf(out, ";; NODATA response\n");
-			}
-			fprintf(out, "rrset:\n");
-			ldns_rr_list_print_fmt(out, fmt, chain->rrset);
-			fprintf(out, "sigs:\n");
-			ldns_rr_list_print_fmt(out, fmt, chain->signatures);
-			fprintf(out, "---\n");
-		} else {
-			fprintf(out, "<no data>\n");
-		}
-	}
-}
-void
-ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain)
-{
-	ldns_dnssec_data_chain_print_fmt(
-			out, ldns_output_format_default, chain);
-}
-
-
-static void
-ldns_dnssec_build_data_chain_dnskey(ldns_resolver *res,
-					    uint16_t qflags,
-					    const ldns_pkt *pkt,
-					    ldns_rr_list *signatures,
-						ldns_dnssec_data_chain *new_chain,
-						ldns_rdf *key_name,
-						ldns_rr_class c) {
-	ldns_rr_list *keys;
-	ldns_pkt *my_pkt;
-	if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
-		new_chain->signatures = ldns_rr_list_clone(signatures);
-		new_chain->parent_type = 0;
-
-		keys = ldns_pkt_rr_list_by_name_and_type(
-				  pkt,
-				 key_name,
-				 LDNS_RR_TYPE_DNSKEY,
-				 LDNS_SECTION_ANY_NOQUESTION
-			  );
-		if (!keys) {
-			my_pkt = ldns_resolver_query(res,
-									key_name,
-									LDNS_RR_TYPE_DNSKEY,
-									c,
-									qflags);
-			if (my_pkt) {
-			keys = ldns_pkt_rr_list_by_name_and_type(
-					  my_pkt,
-					 key_name,
-					 LDNS_RR_TYPE_DNSKEY,
-					 LDNS_SECTION_ANY_NOQUESTION
-				  );
-			new_chain->parent = ldns_dnssec_build_data_chain(res,
-													qflags,
-													keys,
-													my_pkt,
-													NULL);
-			new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
-			ldns_pkt_free(my_pkt);
-			}
-		} else {
-			new_chain->parent = ldns_dnssec_build_data_chain(res,
-													qflags,
-													keys,
-													pkt,
-													NULL);
-			new_chain->parent->packet_qtype = LDNS_RR_TYPE_DNSKEY;
-		}
-		ldns_rr_list_deep_free(keys);
-	}
-}
-
-static void
-ldns_dnssec_build_data_chain_other(ldns_resolver *res,
-					    uint16_t qflags,
-						ldns_dnssec_data_chain *new_chain,
-						ldns_rdf *key_name,
-						ldns_rr_class c,
-						ldns_rr_list *dss)
-{
-	/* 'self-signed', parent is a DS */
-	
-	/* okay, either we have other keys signing the current one,
-	 * or the current
-	 * one should have a DS record in the parent zone.
-	 * How do we find this out? Try both?
-	 *
-	 * request DNSKEYS for current zone,
-	 * add all signatures to current level
-	 */
-	ldns_pkt *my_pkt;
-	ldns_rr_list *signatures2;
-	
-	new_chain->parent_type = 1;
-
-	my_pkt = ldns_resolver_query(res,
-							key_name,
-							LDNS_RR_TYPE_DS,
-							c,
-							qflags);
-	if (my_pkt) {
-	dss = ldns_pkt_rr_list_by_name_and_type(my_pkt,
-									key_name,
-									LDNS_RR_TYPE_DS,
-									LDNS_SECTION_ANY_NOQUESTION
-									);
-	if (dss) {
-		new_chain->parent = ldns_dnssec_build_data_chain(res,
-												qflags,
-												dss,
-												my_pkt,
-												NULL);
-		new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
-		ldns_rr_list_deep_free(dss);
-	}
-	ldns_pkt_free(my_pkt);
-	}
-
-	my_pkt = ldns_resolver_query(res,
-							key_name,
-							LDNS_RR_TYPE_DNSKEY,
-							c,
-							qflags);
-	if (my_pkt) {
-	signatures2 = ldns_pkt_rr_list_by_name_and_type(my_pkt,
-										   key_name,
-										   LDNS_RR_TYPE_RRSIG,
-										   LDNS_SECTION_ANSWER);
-	if (signatures2) {
-		if (new_chain->signatures) {
-			printf("There were already sigs!\n");
-			ldns_rr_list_deep_free(new_chain->signatures);
-			printf("replacing the old sigs\n");
-		}
-		new_chain->signatures = signatures2;
-	}
-	ldns_pkt_free(my_pkt);
-	}
-}
-
-static ldns_dnssec_data_chain *
-ldns_dnssec_build_data_chain_nokeyname(ldns_resolver *res,
-                                       uint16_t qflags,
-                                       ldns_rr *orig_rr,
-                                       const ldns_rr_list *rrset,
-                                       ldns_dnssec_data_chain *new_chain)
-{
-	ldns_rdf *possible_parent_name;
-	ldns_pkt *my_pkt;
-	/* apparently we were not able to find a signing key, so
-	   we assume the chain ends here
-	*/
-	/* try parents for auth denial of DS */
-	if (orig_rr) {
-		possible_parent_name = ldns_rr_owner(orig_rr);
-	} else if (rrset && ldns_rr_list_rr_count(rrset) > 0) {
-		possible_parent_name = ldns_rr_owner(ldns_rr_list_rr(rrset, 0));
-	} else {
-		/* no information to go on, give up */
-		return new_chain;
-	}
-
-	my_pkt = ldns_resolver_query(res,
-	              possible_parent_name,
-	              LDNS_RR_TYPE_DS,
-	              LDNS_RR_CLASS_IN,
-	              qflags);
-	if (!my_pkt) {
-		return new_chain;
-	}
-
-	if (ldns_pkt_ancount(my_pkt) > 0) {
-		/* add error, no sigs but DS in parent */
-		/*ldns_pkt_print(stdout, my_pkt);*/
-		ldns_pkt_free(my_pkt);
-	} else {
-		/* are there signatures? */
-		new_chain->parent =  ldns_dnssec_build_data_chain(res, 
-		                          qflags, 
-		                          NULL,
-		                          my_pkt,
-		                          NULL);
-
-		new_chain->parent->packet_qtype = LDNS_RR_TYPE_DS;
-		
-	}
-	return new_chain;
-}
-
-
-ldns_dnssec_data_chain *
-ldns_dnssec_build_data_chain(ldns_resolver *res,
-					    uint16_t qflags,
-					    const ldns_rr_list *rrset,
-					    const ldns_pkt *pkt,
-					    ldns_rr *orig_rr)
-{
-	ldns_rr_list *signatures = NULL;
-	ldns_rr_list *dss = NULL;
-	
-	ldns_rr_list *my_rrset;
-
-	ldns_pkt *my_pkt;
-
-	ldns_rdf *name = NULL, *key_name = NULL;
-	ldns_rr_type type = 0;
-	ldns_rr_class c = 0;
-
-	bool other_rrset = false;
-
-	ldns_dnssec_data_chain *new_chain = ldns_dnssec_data_chain_new();
-
-	assert(pkt != NULL);
-
-	if (!ldns_dnssec_pkt_has_rrsigs(pkt)) {
-		/* hmm. no dnssec data in the packet. go up to try and deny
-		 * DS? */
-		return new_chain;
-	}
-
-	if (orig_rr) {
-		new_chain->rrset = ldns_rr_list_new();
-		ldns_rr_list_push_rr(new_chain->rrset, orig_rr);
-		new_chain->parent = ldns_dnssec_build_data_chain(res,
-											    qflags,
-											    rrset,
-											    pkt,
-											    NULL);
-		new_chain->packet_rcode = ldns_pkt_get_rcode(pkt);
-		new_chain->packet_qtype = ldns_rr_get_type(orig_rr);
-		if (ldns_pkt_ancount(pkt) == 0) {
-			new_chain->packet_nodata = true;
-		}
-		return new_chain;
-	}
-	
-	if (!rrset || ldns_rr_list_rr_count(rrset) < 1) {
-		/* hmm, no data, do we have denial? only works if pkt was given,
-		   otherwise caller has to do the check himself */
-		new_chain->packet_nodata = true;
-		if (pkt) {
-			my_rrset = ldns_pkt_rr_list_by_type(pkt,
-										 LDNS_RR_TYPE_NSEC,
-										 LDNS_SECTION_ANY_NOQUESTION
-										 );
-			if (my_rrset) {
-				if (ldns_rr_list_rr_count(my_rrset) > 0) {
-					type = LDNS_RR_TYPE_NSEC;
-					other_rrset = true;
-				} else {
-					ldns_rr_list_deep_free(my_rrset);
-					my_rrset = NULL;
-				}
-			} else {
-				/* nothing, try nsec3 */
-				my_rrset = ldns_pkt_rr_list_by_type(pkt,
-						     LDNS_RR_TYPE_NSEC3,
-							LDNS_SECTION_ANY_NOQUESTION);
-				if (my_rrset) {
-					if (ldns_rr_list_rr_count(my_rrset) > 0) {
-						type = LDNS_RR_TYPE_NSEC3;
-						other_rrset = true;
-					} else {
-						ldns_rr_list_deep_free(my_rrset);
-						my_rrset = NULL;
-					}
-				} else {
-					/* nothing, stop */
-					/* try parent zone? for denied insecure? */
-					return new_chain;
-				}
-			}
-		} else {
-			return new_chain;
-		}
-	} else {
-		my_rrset = (ldns_rr_list *) rrset;
-	}
-	
-	if (my_rrset && ldns_rr_list_rr_count(my_rrset) > 0) {
-		new_chain->rrset = ldns_rr_list_clone(my_rrset);
-		name = ldns_rr_owner(ldns_rr_list_rr(my_rrset, 0));
-		type = ldns_rr_get_type(ldns_rr_list_rr(my_rrset, 0));
-		c = ldns_rr_get_class(ldns_rr_list_rr(my_rrset, 0));
-	}
-	
-	if (other_rrset) {
-		ldns_rr_list_deep_free(my_rrset);
-	}
-	
-	/* normally there will only be 1 signature 'set'
-	   but there can be more than 1 denial (wildcards)
-	   so check for NSEC
-	*/
-	if (type == LDNS_RR_TYPE_NSEC || type == LDNS_RR_TYPE_NSEC3) {
-		/* just throw in all signatures, the tree builder must sort
-		   this out */
-		if (pkt) {
-			signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
-		} else {
-			my_pkt = ldns_resolver_query(res, name, type, c, qflags);
-			if (my_pkt) {
-			signatures = ldns_dnssec_pkt_get_rrsigs_for_type(pkt, type);
-			ldns_pkt_free(my_pkt);
-			}
-		}
-	} else {
-		if (pkt) {
-			signatures =
-				ldns_dnssec_pkt_get_rrsigs_for_name_and_type(pkt,
-													name,
-													type);
-		}
-		if (!signatures) {
-			my_pkt = ldns_resolver_query(res, name, type, c, qflags);
-			if (my_pkt) {
-			signatures =
-				ldns_dnssec_pkt_get_rrsigs_for_name_and_type(my_pkt,
-													name,
-													type);
-			ldns_pkt_free(my_pkt);
-			}
-		}
-	}
-
-	if (signatures && ldns_rr_list_rr_count(signatures) > 0) {
-		key_name = ldns_rr_rdf(ldns_rr_list_rr(signatures, 0), 7);
-	}
-	if (!key_name) {
-		if (signatures) {
-			ldns_rr_list_deep_free(signatures);
-		}
-		return ldns_dnssec_build_data_chain_nokeyname(res,
-		                                              qflags,
-		                                              orig_rr,
-		                                              rrset,
-		                                              new_chain);
-	}
-	if (type != LDNS_RR_TYPE_DNSKEY) {
-		ldns_dnssec_build_data_chain_dnskey(res,
-		                                    qflags,
-		                                    pkt,
-		                                    signatures,
-		                                    new_chain,
-		                                    key_name,
-		                                    c
-		                                   );
-	} else {
-		ldns_dnssec_build_data_chain_other(res,
-		                                   qflags,
-		                                   new_chain,
-		                                   key_name,
-		                                   c,
-		                                   dss
-		                                  );
-	}
-	if (signatures) {
-		ldns_rr_list_deep_free(signatures);
-	}
-	return new_chain;
-}
-
-ldns_dnssec_trust_tree *
-ldns_dnssec_trust_tree_new(void)
-{
-	ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
-										   1);
-        if(!new_tree) return NULL;
-	new_tree->rr = NULL;
-	new_tree->rrset = NULL;
-	new_tree->parent_count = 0;
-
-	return new_tree;
-}
-
-void
-ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree)
-{
-	size_t i;
-	if (tree) {
-		for (i = 0; i < tree->parent_count; i++) {
-			ldns_dnssec_trust_tree_free(tree->parents[i]);
-		}
-	}
-	LDNS_FREE(tree);
-}
-
-size_t
-ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
-{
-	size_t result = 0;
-	size_t parent = 0;
-	size_t i;
-	
-	for (i = 0; i < tree->parent_count; i++) {
-		parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
-		if (parent > result) {
-			result = parent;
-		}
-	}
-	return 1 + result;
-}
-
-/* TODO ldns_ */
-static void
-print_tabs(FILE *out, size_t nr, uint8_t *map, size_t treedepth)
-{
-	size_t i;
-	for (i = 0; i < nr; i++) {
-		if (i == nr - 1) {
-			fprintf(out, "|---");
-		} else if (map && i < treedepth && map[i] == 1) {
-			fprintf(out, "|   ");
-		} else {
-			fprintf(out, "    ");
-		}
-	}
-}
-
-static void
-ldns_dnssec_trust_tree_print_sm_fmt(FILE *out, 
-		const ldns_output_format *fmt,
-		ldns_dnssec_trust_tree *tree,
-		size_t tabs,
-		bool extended,
-		uint8_t *sibmap,
-		size_t treedepth)
-{
-	size_t i;
-	const ldns_rr_descriptor *descriptor;
-	bool mapset = false;
-	
-	if (!sibmap) {
-		treedepth = ldns_dnssec_trust_tree_depth(tree);
-		sibmap = LDNS_XMALLOC(uint8_t, treedepth);
-                if(!sibmap)
-                        return; /* mem err */
-		memset(sibmap, 0, treedepth);
-		mapset = true;
-	}
-	
-	if (tree) {
-		if (tree->rr) {
-			print_tabs(out, tabs, sibmap, treedepth);
-			ldns_rdf_print(out, ldns_rr_owner(tree->rr));
-			descriptor = ldns_rr_descript(ldns_rr_get_type(tree->rr));
-
-			if (descriptor->_name) {
-				fprintf(out, " (%s", descriptor->_name);
-			} else {
-				fprintf(out, " (TYPE%d", 
-					   ldns_rr_get_type(tree->rr));
-			}
-			if (tabs > 0) {
-				if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DNSKEY) {
-					fprintf(out, " keytag: %u",
-					        (unsigned int) ldns_calc_keytag(tree->rr));
-					fprintf(out, " alg: ");
-					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
-					fprintf(out, " flags: ");
-					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
-				} else if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_DS) {
-					fprintf(out, " keytag: ");
-					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
-					fprintf(out, " digest type: ");
-					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 2));
-				}
-				if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NSEC) {
-					fprintf(out, " ");
-					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 0));
-					fprintf(out, " ");
-					ldns_rdf_print(out, ldns_rr_rdf(tree->rr, 1));
-				}
-			}
-			
-			fprintf(out, ")\n");
-			for (i = 0; i < tree->parent_count; i++) {
-				if (tree->parent_count > 1 && i < tree->parent_count - 1) {
-					sibmap[tabs] = 1;
-				} else {
-					sibmap[tabs] = 0;
-				}
-				/* only print errors */
-				if (ldns_rr_get_type(tree->parents[i]->rr) == 
-				    LDNS_RR_TYPE_NSEC ||
-				    ldns_rr_get_type(tree->parents[i]->rr) ==
-				    LDNS_RR_TYPE_NSEC3) {
-					if (tree->parent_status[i] == LDNS_STATUS_OK) {
-						print_tabs(out, tabs + 1, sibmap, treedepth);
-						if (tabs == 0 &&
-						    ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS &&
-							ldns_rr_rd_count(tree->rr) > 0) {
-							fprintf(out, "Existence of DS is denied by:\n");
-						} else {
-							fprintf(out, "Existence is denied by:\n");
-						}
-					} else {
-						/* NS records aren't signed */
-						if (ldns_rr_get_type(tree->rr) == LDNS_RR_TYPE_NS) {
-							fprintf(out, "Existence of DS is denied by:\n");
-						} else {
-							print_tabs(out, tabs + 1, sibmap, treedepth);
-							fprintf(out,
-								   "Error in denial of existence: %s\n",
-								   ldns_get_errorstr_by_id(
-									   tree->parent_status[i]));
-						}
-					}
-				} else
-					if (tree->parent_status[i] != LDNS_STATUS_OK) {
-						print_tabs(out, tabs + 1, sibmap, treedepth);
-						fprintf(out,
-							   "%s:\n",
-							   ldns_get_errorstr_by_id(
-							       tree->parent_status[i]));
-						if (tree->parent_status[i]
-						    == LDNS_STATUS_SSL_ERR) {
-							printf("; SSL Error: ");
-							ERR_load_crypto_strings();
-							ERR_print_errors_fp(stdout);
-							printf("\n");
-						}
-						ldns_rr_print_fmt(out, fmt, 
-							tree->
-							parent_signature[i]);
-						printf("For RRset:\n");
-						ldns_rr_list_print_fmt(out, fmt,
-								tree->rrset);
-						printf("With key:\n");
-						ldns_rr_print_fmt(out, fmt,
-							tree->parents[i]->rr);
-					}
-				ldns_dnssec_trust_tree_print_sm_fmt(out, fmt,
-						tree->parents[i],
-						tabs+1,
-						extended,
-						sibmap,
-						treedepth);
-			}
-		} else {
-			print_tabs(out, tabs, sibmap, treedepth);
-			fprintf(out, "<no data>\n");
-		}
-	} else {
-		fprintf(out, "<null pointer>\n");
-	}
-	
-	if (mapset) {
-		LDNS_FREE(sibmap);
-	}
-}
-
-void
-ldns_dnssec_trust_tree_print_fmt(FILE *out, const ldns_output_format *fmt,
-		ldns_dnssec_trust_tree *tree,
-		size_t tabs,
-		bool extended)
-{
-	ldns_dnssec_trust_tree_print_sm_fmt(out, fmt, 
-			tree, tabs, extended, NULL, 0);
-}
-
-void
-ldns_dnssec_trust_tree_print(FILE *out,
-		ldns_dnssec_trust_tree *tree,
-		size_t tabs,
-		bool extended)
-{
-	ldns_dnssec_trust_tree_print_fmt(out, ldns_output_format_default, 
-			tree, tabs, extended);
-}
-
-
-ldns_status
-ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
-                                  const ldns_dnssec_trust_tree *parent,
-                                  const ldns_rr *signature,
-                                  const ldns_status parent_status)
-{
-	if (tree
-	    && parent
-	    && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
-		/*
-		  printf("Add parent for: ");
-		  ldns_rr_print(stdout, tree->rr);
-		  printf("parent: ");
-		  ldns_rr_print(stdout, parent->rr);
-		*/
-		tree->parents[tree->parent_count] =
-			(ldns_dnssec_trust_tree *) parent;
-		tree->parent_status[tree->parent_count] = parent_status;
-		tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
-		tree->parent_count++;
-		return LDNS_STATUS_OK;
-	} else {
-		return LDNS_STATUS_ERR;
-	}
-}
-
-/* if rr is null, take the first from the rrset */
-ldns_dnssec_trust_tree *
-ldns_dnssec_derive_trust_tree_time(
-		ldns_dnssec_data_chain *data_chain, 
-		ldns_rr *rr, 
-		time_t check_time
-		)
-{
-	ldns_rr_list *cur_rrset;
-	ldns_rr_list *cur_sigs;
-	ldns_rr *cur_rr = NULL;
-	ldns_rr *cur_sig_rr;
-	size_t i, j;
-
-	ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
-        if(!new_tree)
-                return NULL;
-	
-	if (data_chain && data_chain->rrset) {
-		cur_rrset = data_chain->rrset;
-	
-		cur_sigs = data_chain->signatures;
-
-		if (rr) {
-			cur_rr = rr;
-		}
-
-		if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
-			cur_rr = ldns_rr_list_rr(cur_rrset, 0);
-		}
-
-		if (cur_rr) {
-			new_tree->rr = cur_rr;
-			new_tree->rrset = cur_rrset;
-			/* there are three possibilities:
-			   1 - 'normal' rrset, signed by a key
-			   2 - dnskey signed by other dnskey
-			   3 - dnskey proven by higher level DS
-			   (data denied by nsec is a special case that can
-			   occur in multiple places)
-				   
-			*/
-			if (cur_sigs) {
-				for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
-					/* find the appropriate key in the parent list */
-					cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
-
-					if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
-						if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
-										   ldns_rr_owner(cur_rr)))
-							{
-								/* find first that does match */
-
-								for (j = 0;
-								     j < ldns_rr_list_rr_count(cur_rrset) && 
-										ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
-								     j++) {
-									cur_rr = ldns_rr_list_rr(cur_rrset, j);
-									
-								}
-								if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr), 
-												   ldns_rr_owner(cur_rr)))
-									{
-										break;
-									}
-							}
-							
-					}
-					/* option 1 */
-					if (data_chain->parent) {
-						ldns_dnssec_derive_trust_tree_normal_rrset_time(
-						    new_tree,
-						    data_chain,
-						    cur_sig_rr,
-						    check_time);
-					}
-
-					/* option 2 */
-					ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
-					    new_tree,
-					    data_chain,
-					    cur_rr,
-					    cur_sig_rr,
-					    check_time);
-				}
-					
-				ldns_dnssec_derive_trust_tree_ds_rrset_time(
-						new_tree, data_chain, 
-						cur_rr, check_time);
-			} else {
-				/* no signatures? maybe it's nsec data */
-					
-				/* just add every rr from parent as new parent */
-				ldns_dnssec_derive_trust_tree_no_sig_time(
-					new_tree, data_chain, check_time);
-			}
-		}
-	}
-
-	return new_tree;
-}
-
-ldns_dnssec_trust_tree *
-ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
-{
-	return ldns_dnssec_derive_trust_tree_time(data_chain, rr, ldns_time(NULL));
-}
-
-void
-ldns_dnssec_derive_trust_tree_normal_rrset_time(
-		ldns_dnssec_trust_tree *new_tree, 
-		ldns_dnssec_data_chain *data_chain, 
-		ldns_rr *cur_sig_rr,
-		time_t check_time)
-{
-	size_t i, j;
-	ldns_rr_list *cur_rrset = ldns_rr_list_clone(data_chain->rrset); 
-	ldns_dnssec_trust_tree *cur_parent_tree;
-	ldns_rr *cur_parent_rr;
-	uint16_t cur_keytag;
-	ldns_rr_list *tmp_rrset = NULL;
-	ldns_status cur_status;
-
-	cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
-	
-	for (j = 0; j < ldns_rr_list_rr_count(data_chain->parent->rrset); j++) {
-		cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
-		if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
-			if (ldns_calc_keytag(cur_parent_rr) == cur_keytag) {
-
-				/* TODO: check wildcard nsec too */
-				if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
-					tmp_rrset = cur_rrset;
-					if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
-					    == LDNS_RR_TYPE_NSEC ||
-					    ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0))
-					    == LDNS_RR_TYPE_NSEC3) {
-						/* might contain different names! 
-						   sort and split */
-						ldns_rr_list_sort(cur_rrset);
-						assert(tmp_rrset == cur_rrset);
-						tmp_rrset = ldns_rr_list_pop_rrset(cur_rrset);
-						
-						/* with nsecs, this might be the wrong one */
-						while (tmp_rrset &&
-						       ldns_rr_list_rr_count(cur_rrset) > 0 &&
-						       ldns_dname_compare(
-								ldns_rr_owner(ldns_rr_list_rr(
-										        tmp_rrset, 0)),
-								ldns_rr_owner(cur_sig_rr)) != 0) {
-							ldns_rr_list_deep_free(tmp_rrset);
-							tmp_rrset =
-								ldns_rr_list_pop_rrset(cur_rrset);
-						}
-					}
-					cur_status = ldns_verify_rrsig_time(
-							tmp_rrset, 
-							cur_sig_rr, 
-							cur_parent_rr,
-							check_time);
-					if (tmp_rrset && tmp_rrset != cur_rrset
-							) {
-						ldns_rr_list_deep_free(
-								tmp_rrset);
-						tmp_rrset = NULL;
-					}
-					/* avoid dupes */
-					for (i = 0; i < new_tree->parent_count; i++) {
-						if (cur_parent_rr == new_tree->parents[i]->rr) {
-							goto done;
-						}
-					}
-
-					cur_parent_tree =
-						ldns_dnssec_derive_trust_tree_time(
-								data_chain->parent,
-						                cur_parent_rr,
-								check_time);
-					(void)ldns_dnssec_trust_tree_add_parent(new_tree,
-					           cur_parent_tree,
-					           cur_sig_rr,
-					           cur_status);
-				}
-			}
-		}
-	}
- done:
-	ldns_rr_list_deep_free(cur_rrset);
-}
-
-void
-ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
-                                           ldns_dnssec_data_chain *data_chain,
-                                           ldns_rr *cur_sig_rr)
-{
-	ldns_dnssec_derive_trust_tree_normal_rrset_time(
-			new_tree, data_chain, cur_sig_rr, ldns_time(NULL));
-}
-
-void
-ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
-		ldns_dnssec_trust_tree *new_tree, 
-		ldns_dnssec_data_chain *data_chain, 
-		ldns_rr *cur_rr, 
-		ldns_rr *cur_sig_rr,
-		time_t check_time)
-{
-	size_t j;
-	ldns_rr_list *cur_rrset = data_chain->rrset;
-	ldns_dnssec_trust_tree *cur_parent_tree;
-	ldns_rr *cur_parent_rr;
-	uint16_t cur_keytag;
-	ldns_status cur_status;
-
-	cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
-
-	for (j = 0; j < ldns_rr_list_rr_count(cur_rrset); j++) {
-		cur_parent_rr = ldns_rr_list_rr(cur_rrset, j);
-		if (cur_parent_rr != cur_rr &&
-		    ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DNSKEY) {
-			if (ldns_calc_keytag(cur_parent_rr) == cur_keytag
-			    ) {
-				cur_parent_tree = ldns_dnssec_trust_tree_new();
-				cur_parent_tree->rr = cur_parent_rr;
-				cur_parent_tree->rrset = cur_rrset;
-				cur_status = ldns_verify_rrsig_time(
-						cur_rrset, cur_sig_rr, 
-						cur_parent_rr, check_time);
-				(void) ldns_dnssec_trust_tree_add_parent(new_tree,
-				            cur_parent_tree, cur_sig_rr, cur_status);
-			}
-		}
-	}
-}
-
-void
-ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
-                                           ldns_dnssec_data_chain *data_chain,
-                                           ldns_rr *cur_rr,
-                                           ldns_rr *cur_sig_rr)
-{
-	ldns_dnssec_derive_trust_tree_dnskey_rrset_time(
-			new_tree, data_chain, cur_rr, cur_sig_rr, ldns_time(NULL));
-}
-
-void
-ldns_dnssec_derive_trust_tree_ds_rrset_time(
-		ldns_dnssec_trust_tree *new_tree,
-		ldns_dnssec_data_chain *data_chain, 
-		ldns_rr *cur_rr,
-		time_t check_time)
-{
-	size_t j, h;
-	ldns_rr_list *cur_rrset = data_chain->rrset;
-	ldns_dnssec_trust_tree *cur_parent_tree;
-	ldns_rr *cur_parent_rr;
-
-	/* try the parent to see whether there are DSs there */
-	if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_DNSKEY &&
-	    data_chain->parent &&
-	    data_chain->parent->rrset
-	    ) {
-		for (j = 0;
-			j < ldns_rr_list_rr_count(data_chain->parent->rrset);
-			j++) {
-			cur_parent_rr = ldns_rr_list_rr(data_chain->parent->rrset, j);
-			if (ldns_rr_get_type(cur_parent_rr) == LDNS_RR_TYPE_DS) {
-				for (h = 0; h < ldns_rr_list_rr_count(cur_rrset); h++) {
-					cur_rr = ldns_rr_list_rr(cur_rrset, h);
-					if (ldns_rr_compare_ds(cur_rr, cur_parent_rr)) {
-						cur_parent_tree =
-							ldns_dnssec_derive_trust_tree_time(
-							    data_chain->parent, 
-							    cur_parent_rr,
-							    check_time);
-						(void) ldns_dnssec_trust_tree_add_parent(
-						            new_tree,
-						            cur_parent_tree,
-						            NULL,
-						            LDNS_STATUS_OK);
-					} else {
-						/*ldns_rr_print(stdout, cur_parent_rr);*/
-					}
-				}
-			}
-		}
-	}
-}
-
-void
-ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
-                                       ldns_dnssec_data_chain *data_chain,
-                                       ldns_rr *cur_rr)
-{
-	ldns_dnssec_derive_trust_tree_ds_rrset_time(
-			new_tree, data_chain, cur_rr, ldns_time(NULL));
-}
-
-void
-ldns_dnssec_derive_trust_tree_no_sig_time(
-		ldns_dnssec_trust_tree *new_tree, 
-		ldns_dnssec_data_chain *data_chain,
-		time_t check_time)
-{
-	size_t i;
-	ldns_rr_list *cur_rrset;
-	ldns_rr *cur_parent_rr;
-	ldns_dnssec_trust_tree *cur_parent_tree;
-	ldns_status result;
-	
-	if (data_chain->parent && data_chain->parent->rrset) {
-		cur_rrset = data_chain->parent->rrset;
-		/* nsec? */
-		if (cur_rrset && ldns_rr_list_rr_count(cur_rrset) > 0) {
-			if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
-			    LDNS_RR_TYPE_NSEC3) {
-				result = ldns_dnssec_verify_denial_nsec3(
-					        new_tree->rr,
-						   cur_rrset,
-						   data_chain->parent->signatures,
-						   data_chain->packet_rcode,
-						   data_chain->packet_qtype,
-						   data_chain->packet_nodata);
-			} else if (ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0)) ==
-					 LDNS_RR_TYPE_NSEC) {
-				result = ldns_dnssec_verify_denial(
-					        new_tree->rr,
-						   cur_rrset,
-						   data_chain->parent->signatures);
-			} else {
-				/* unsigned zone, unsigned parent */
-				result = LDNS_STATUS_OK;
-			}
-		} else {
-			result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
-		}
-		for (i = 0; i < ldns_rr_list_rr_count(cur_rrset); i++) {
-			cur_parent_rr = ldns_rr_list_rr(cur_rrset, i);
-			cur_parent_tree = 
-				ldns_dnssec_derive_trust_tree_time(
-						data_chain->parent, 
-						cur_parent_rr,
-						check_time);
-			(void) ldns_dnssec_trust_tree_add_parent(new_tree,
-			            cur_parent_tree, NULL, result);
-		}
-	}
-}
-
-void
-ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
-                                     ldns_dnssec_data_chain *data_chain)
-{
-	ldns_dnssec_derive_trust_tree_no_sig_time(
-			new_tree, data_chain, ldns_time(NULL));
-}
-
-/*
- * returns OK if there is a path from tree to key with only OK
- * the (first) error in between otherwise
- * or NOT_FOUND if the key wasn't present at all
- */
-ldns_status
-ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree,
-							  ldns_rr_list *trusted_keys)
-{
-	size_t i;
-	ldns_status result = LDNS_STATUS_CRYPTO_NO_DNSKEY;
-	bool equal;
-	ldns_status parent_result;
-	
-	if (tree && trusted_keys && ldns_rr_list_rr_count(trusted_keys) > 0)
-		{ if (tree->rr) {
-				for (i = 0; i < ldns_rr_list_rr_count(trusted_keys); i++) {
-					equal = ldns_rr_compare_ds(
-							  tree->rr,
-							  ldns_rr_list_rr(trusted_keys, i));
-					if (equal) {
-						result = LDNS_STATUS_OK;
-						return result;
-					}
-				}
-			}
-			for (i = 0; i < tree->parent_count; i++) {
-				parent_result =
-					ldns_dnssec_trust_tree_contains_keys(tree->parents[i],
-												  trusted_keys);
-				if (parent_result != LDNS_STATUS_CRYPTO_NO_DNSKEY) {
-					if (tree->parent_status[i] != LDNS_STATUS_OK) {
-						result = tree->parent_status[i];
-					} else {
-						if (tree->rr &&
-						    ldns_rr_get_type(tree->rr)
-						    == LDNS_RR_TYPE_NSEC &&
-						    parent_result == LDNS_STATUS_OK
-						    ) {
-							result =
-								LDNS_STATUS_DNSSEC_EXISTENCE_DENIED;
-						} else {
-							result = parent_result;
-						}
-					}
-				}
-			}
-		} else {
-		result = LDNS_STATUS_ERR;
-	}
-	
-	return result;
-}
-
-ldns_status
-ldns_verify_time(
-		ldns_rr_list *rrset,
-		ldns_rr_list *rrsig, 
-		const ldns_rr_list *keys, 
-		time_t check_time,
-		ldns_rr_list *good_keys
-		)
-{
-	uint16_t i;
-	ldns_status verify_result = LDNS_STATUS_ERR;
-
-	if (!rrset || !rrsig || !keys) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (ldns_rr_list_rr_count(rrset) < 1) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (ldns_rr_list_rr_count(rrsig) < 1) {
-		return LDNS_STATUS_CRYPTO_NO_RRSIG;
-	}
-	
-	if (ldns_rr_list_rr_count(keys) < 1) {
-		verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
-	} else {
-		for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
-			ldns_status s = ldns_verify_rrsig_keylist_time(
-					rrset, ldns_rr_list_rr(rrsig, i), 
-					keys, check_time, good_keys);
-			/* try a little to get more descriptive error */
-			if(s == LDNS_STATUS_OK) {
-				verify_result = LDNS_STATUS_OK;
-			} else if(verify_result == LDNS_STATUS_ERR)
-				verify_result = s;
-			else if(s !=  LDNS_STATUS_ERR && verify_result ==
-				LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY)
-				verify_result = s;
-		}
-	}
-	return verify_result;
-}
-
-ldns_status
-ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys, 
-		  ldns_rr_list *good_keys)
-{
-	return ldns_verify_time(rrset, rrsig, keys, ldns_time(NULL), good_keys);
-}
-
-ldns_status
-ldns_verify_notime(ldns_rr_list *rrset, ldns_rr_list *rrsig,
-	const ldns_rr_list *keys, ldns_rr_list *good_keys)
-{
-	uint16_t i;
-	ldns_status verify_result = LDNS_STATUS_ERR;
-
-	if (!rrset || !rrsig || !keys) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (ldns_rr_list_rr_count(rrset) < 1) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (ldns_rr_list_rr_count(rrsig) < 1) {
-		return LDNS_STATUS_CRYPTO_NO_RRSIG;
-	}
-
-	if (ldns_rr_list_rr_count(keys) < 1) {
-		verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
-	} else {
-		for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
-			ldns_status s = ldns_verify_rrsig_keylist_notime(rrset,
-				ldns_rr_list_rr(rrsig, i), keys, good_keys);
-
-			/* try a little to get more descriptive error */
-			if (s == LDNS_STATUS_OK) {
-				verify_result = LDNS_STATUS_OK;
-			} else if (verify_result == LDNS_STATUS_ERR) {
-				verify_result = s;
-			} else if (s !=  LDNS_STATUS_ERR && verify_result ==
-				LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
-				verify_result = s;
-			}
-		}
-	}
-	return verify_result;
-}
-
-ldns_rr_list *
-ldns_fetch_valid_domain_keys_time(const ldns_resolver *res,
-                             const ldns_rdf *domain,
-                             const ldns_rr_list *keys,
-			     time_t check_time,
-                             ldns_status *status)
-{
-	ldns_rr_list * trusted_keys = NULL;
-	ldns_rr_list * ds_keys = NULL;
-	ldns_rdf * prev_parent_domain;
-	ldns_rdf *      parent_domain;
-	ldns_rr_list * parent_keys = NULL;
-
-	if (res && domain && keys) {
-
-		if ((trusted_keys = ldns_validate_domain_dnskey_time(res,
-                                         domain, keys, check_time))) {
-			*status = LDNS_STATUS_OK;
-		} else {
-			/* No trusted keys in this domain, we'll have to find some in the parent domain */
-			*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
-
-			parent_domain = ldns_dname_left_chop(domain);
-			while (parent_domain && /* Fail if we are at the root*/
-					ldns_rdf_size(parent_domain) > 0) {
-	
-				if ((parent_keys = 
-					ldns_fetch_valid_domain_keys_time(res,
-					     parent_domain,
-					     keys,
-					     check_time,
-					     status))) {
-					/* Check DS records */
-					if ((ds_keys =
-						ldns_validate_domain_ds_time(res,
-						     domain,
-						     parent_keys,
-						     check_time))) {
-						trusted_keys =
-						ldns_fetch_valid_domain_keys_time(
-								res, 
-								domain, 
-								ds_keys, 
-								check_time,
-								status);
-						ldns_rr_list_deep_free(ds_keys);
-					} else {
-						/* No valid DS at the parent -- fail */
-						*status = LDNS_STATUS_CRYPTO_NO_TRUSTED_DS ;
-					}
-					ldns_rr_list_deep_free(parent_keys);
-					break;
-				} else {
-					parent_domain = ldns_dname_left_chop((
-						prev_parent_domain 
-							= parent_domain
-						));
-					ldns_rdf_deep_free(prev_parent_domain);
-				}
-			}
-			if (parent_domain) {
-				ldns_rdf_deep_free(parent_domain);
-			}
-		}
-	}
-	return trusted_keys;
-}
-
-ldns_rr_list *
-ldns_fetch_valid_domain_keys(const ldns_resolver *res,
-                             const ldns_rdf *domain,
-                             const ldns_rr_list *keys,
-                             ldns_status *status)
-{
-	return ldns_fetch_valid_domain_keys_time(
-			res, domain, keys, ldns_time(NULL), status);
-}
-
-ldns_rr_list *
-ldns_validate_domain_dnskey_time(
-		const ldns_resolver * res,
-		const ldns_rdf * domain,
-		const ldns_rr_list * keys,
-		time_t check_time
-		)
-{
-	ldns_pkt * keypkt;
-	ldns_rr * cur_key;
-	uint16_t key_i; uint16_t key_j; uint16_t key_k;
-	uint16_t sig_i; ldns_rr * cur_sig;
-
-	ldns_rr_list * domain_keys = NULL;
-	ldns_rr_list * domain_sigs = NULL;
-	ldns_rr_list * trusted_keys = NULL;
-
-	/* Fetch keys for the domain */
-	keypkt = ldns_resolver_query(res, domain,
-		LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, LDNS_RD);
-	if (keypkt) {
-		domain_keys = ldns_pkt_rr_list_by_type(keypkt,
-									    LDNS_RR_TYPE_DNSKEY,
-									    LDNS_SECTION_ANSWER);
-		domain_sigs = ldns_pkt_rr_list_by_type(keypkt,
-									    LDNS_RR_TYPE_RRSIG,
-									    LDNS_SECTION_ANSWER);
-
-		/* Try to validate the record using our keys */
-		for (key_i=0; key_i< ldns_rr_list_rr_count(domain_keys); key_i++) {
-      
-			cur_key = ldns_rr_list_rr(domain_keys, key_i);
-			for (key_j=0; key_j<ldns_rr_list_rr_count(keys); key_j++) {
-				if (ldns_rr_compare_ds(ldns_rr_list_rr(keys, key_j),
-								   cur_key)) {
-          
-					/* Current key is trusted -- validate */
-					trusted_keys = ldns_rr_list_new();
-          
-					for (sig_i=0;
-						sig_i<ldns_rr_list_rr_count(domain_sigs);
-						sig_i++) {
-						cur_sig = ldns_rr_list_rr(domain_sigs, sig_i);
-						/* Avoid non-matching sigs */
-						if (ldns_rdf2native_int16(
-							   ldns_rr_rrsig_keytag(cur_sig))
-						    == ldns_calc_keytag(cur_key)) {
-							if (ldns_verify_rrsig_time(
-									domain_keys,
-									cur_sig,
-									cur_key,
-									check_time)
-							    == LDNS_STATUS_OK) {
-                
-								/* Push the whole rrset 
-								   -- we can't do much more */
-								for (key_k=0;
-									key_k<ldns_rr_list_rr_count(
-											domain_keys);
-									key_k++) {
-									ldns_rr_list_push_rr(
-									    trusted_keys,
-									    ldns_rr_clone(
-										   ldns_rr_list_rr(
-											  domain_keys,
-											  key_k)));
-								}
-                
-								ldns_rr_list_deep_free(domain_keys);
-								ldns_rr_list_deep_free(domain_sigs);
-								ldns_pkt_free(keypkt);
-								return trusted_keys;
-							}
-						}
-					}
-	  
-					/* Only push our trusted key */
-					ldns_rr_list_push_rr(trusted_keys,
-									 ldns_rr_clone(cur_key));
-				}
-			}
-		}
-
-		ldns_rr_list_deep_free(domain_keys);
-		ldns_rr_list_deep_free(domain_sigs);
-		ldns_pkt_free(keypkt);
-
-	} else {
-		/* LDNS_STATUS_CRYPTO_NO_DNSKEY */
-	}
-    
-	return trusted_keys;
-}
-
-ldns_rr_list *
-ldns_validate_domain_dnskey(const ldns_resolver * res,
-					   const ldns_rdf * domain,
-					   const ldns_rr_list * keys)
-{
-	return ldns_validate_domain_dnskey_time(
-			res, domain, keys, ldns_time(NULL));
-}
-
-ldns_rr_list *
-ldns_validate_domain_ds_time(
-		const ldns_resolver *res, 
-		const ldns_rdf * domain,
-		const ldns_rr_list * keys,
-		time_t check_time)
-{
-	ldns_pkt * dspkt;
-	uint16_t key_i;
-	ldns_rr_list * rrset = NULL;
-	ldns_rr_list * sigs = NULL;
-	ldns_rr_list * trusted_keys = NULL;
-
-	/* Fetch DS for the domain */
-	dspkt = ldns_resolver_query(res, domain,
-		LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, LDNS_RD);
-	if (dspkt) {
-		rrset = ldns_pkt_rr_list_by_type(dspkt,
-								   LDNS_RR_TYPE_DS,
-								   LDNS_SECTION_ANSWER);
-		sigs = ldns_pkt_rr_list_by_type(dspkt,
-								  LDNS_RR_TYPE_RRSIG,
-								  LDNS_SECTION_ANSWER);
-
-		/* Validate sigs */
-		if (ldns_verify_time(rrset, sigs, keys, check_time, NULL)
-			       	== LDNS_STATUS_OK) {
-			trusted_keys = ldns_rr_list_new();
-			for (key_i=0; key_i<ldns_rr_list_rr_count(rrset); key_i++) {
-				ldns_rr_list_push_rr(trusted_keys,
-								 ldns_rr_clone(ldns_rr_list_rr(rrset,
-														 key_i)
-											)
-								 );
-			}
-		}
-
-		ldns_rr_list_deep_free(rrset);
-		ldns_rr_list_deep_free(sigs);
-		ldns_pkt_free(dspkt);
-
-	} else {
-		/* LDNS_STATUS_CRYPTO_NO_DS */
-	}
-
-	return trusted_keys;
-}
-
-ldns_rr_list *
-ldns_validate_domain_ds(const ldns_resolver *res,
-				    const ldns_rdf * domain,
-				    const ldns_rr_list * keys)
-{
-	return ldns_validate_domain_ds_time(res, domain, keys, ldns_time(NULL));
-}
-
-ldns_status
-ldns_verify_trusted_time(
-		ldns_resolver *res, 
-		ldns_rr_list *rrset, 
-		ldns_rr_list * rrsigs, 
-		time_t check_time,
-		ldns_rr_list * validating_keys
-		)
-{
-	uint16_t sig_i; uint16_t key_i;
-	ldns_rr * cur_sig; ldns_rr * cur_key;
-	ldns_rr_list * trusted_keys = NULL;
-	ldns_status result = LDNS_STATUS_ERR;
-
-	if (!res || !rrset || !rrsigs) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (ldns_rr_list_rr_count(rrset) < 1) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (ldns_rr_list_rr_count(rrsigs) < 1) {
-		return LDNS_STATUS_CRYPTO_NO_RRSIG;
-	}
-  
-	/* Look at each sig */
-	for (sig_i=0; sig_i < ldns_rr_list_rr_count(rrsigs); sig_i++) {
-
-		cur_sig = ldns_rr_list_rr(rrsigs, sig_i);
-		/* Get a valid signer key and validate the sig */
-		if ((trusted_keys = ldns_fetch_valid_domain_keys_time(
-					res, 
-					ldns_rr_rrsig_signame(cur_sig), 
-					ldns_resolver_dnssec_anchors(res), 
-					check_time,
-					&result))) {
-
-			for (key_i = 0;
-				key_i < ldns_rr_list_rr_count(trusted_keys);
-				key_i++) {
-				cur_key = ldns_rr_list_rr(trusted_keys, key_i);
-
-				if ((result = ldns_verify_rrsig_time(rrset,
-								cur_sig, 
-								cur_key,
-								check_time))
-				    == LDNS_STATUS_OK) {
-					if (validating_keys) {
-						ldns_rr_list_push_rr(validating_keys,
-										 ldns_rr_clone(cur_key));
-					}
-					ldns_rr_list_deep_free(trusted_keys);
-					return LDNS_STATUS_OK;
-				} 
-			}
-		}
-	}
-
-	ldns_rr_list_deep_free(trusted_keys);
-	return result;
-}
-
-ldns_status
-ldns_verify_trusted(
-		ldns_resolver *res,
-		ldns_rr_list *rrset, 
-		ldns_rr_list * rrsigs, 
-		ldns_rr_list * validating_keys)
-{
-	return ldns_verify_trusted_time(
-			res, rrset, rrsigs, ldns_time(NULL), validating_keys);
-}
-
-
-ldns_status
-ldns_dnssec_verify_denial(ldns_rr *rr,
-                          ldns_rr_list *nsecs,
-                          ldns_rr_list *rrsigs)
-{
-	ldns_rdf *rr_name;
-	ldns_rdf *wildcard_name;
-	ldns_rdf *chopped_dname;
-	ldns_rr *cur_nsec;
-	size_t i;
-	ldns_status result;
-	/* needed for wildcard check on exact match */
-	ldns_rr *rrsig;
-	bool name_covered = false;
-	bool type_covered = false;
-	bool wildcard_covered = false;
-	bool wildcard_type_covered = false;
-
-	wildcard_name = ldns_dname_new_frm_str("*");
-	rr_name = ldns_rr_owner(rr);
-	chopped_dname = ldns_dname_left_chop(rr_name);
-	result = ldns_dname_cat(wildcard_name, chopped_dname);
-	ldns_rdf_deep_free(chopped_dname);
-	if (result != LDNS_STATUS_OK) {
-		return result;
-	}
-	
-	for  (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
-		cur_nsec = ldns_rr_list_rr(nsecs, i);
-		if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
-			/* see section 5.4 of RFC4035, if the label count of the NSEC's
-			   RRSIG is equal, then it is proven that wildcard expansion 
-			   could not have been used to match the request */
-			rrsig = ldns_dnssec_get_rrsig_for_name_and_type(
-					  ldns_rr_owner(cur_nsec),
-					  ldns_rr_get_type(cur_nsec),
-					  rrsigs);
-			if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig))
-			    == ldns_dname_label_count(rr_name)) {
-				wildcard_covered = true;
-			}
-			
-			if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
-									   ldns_rr_get_type(rr))) {
-				type_covered = true;
-			}
-		}
-		if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
-			name_covered = true;
-		}
-		
-		if (ldns_dname_compare(wildcard_name,
-						   ldns_rr_owner(cur_nsec)) == 0) {
-			if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
-									   ldns_rr_get_type(rr))) {
-				wildcard_type_covered = true;
-			}
-		}
-		
-		if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
-			wildcard_covered = true;
-		}
-		
-	}
-	
-	ldns_rdf_deep_free(wildcard_name);
-	
-	if (type_covered || !name_covered) {
-		return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
-	}
-	
-	if (wildcard_type_covered || !wildcard_covered) {
-		return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
-	}
-
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_dnssec_verify_denial_nsec3_match( ldns_rr *rr
-				     , ldns_rr_list *nsecs
-				     , ATTR_UNUSED(ldns_rr_list *rrsigs)
-				     , ldns_pkt_rcode packet_rcode
-				     , ldns_rr_type packet_qtype
-				     , bool packet_nodata
-				     , ldns_rr **match
-				     )
-{
-	ldns_rdf *closest_encloser;
-	ldns_rdf *wildcard;
-	ldns_rdf *hashed_wildcard_name;
-	bool wildcard_covered = false;
-	ldns_rdf *zone_name;
-	ldns_rdf *hashed_name;
-	/* self assignment to suppress uninitialized warning */
-	ldns_rdf *next_closer = next_closer;
-	ldns_rdf *hashed_next_closer;
-	size_t i;
-	ldns_status result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
-
-	if (match) {
-		*match = NULL;
-	}
-
-	zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
-
-	/* section 8.4 */
-	if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
-		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
-						   ldns_rr_owner(rr),
-						   ldns_rr_get_type(rr),
-						   nsecs);
-                if(!closest_encloser) {
-                        result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
-                        goto done;
-                }
-
-		wildcard = ldns_dname_new_frm_str("*");
-		(void) ldns_dname_cat(wildcard, closest_encloser);
-
-		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
-			hashed_wildcard_name =
-				ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
-										 wildcard
-										 );
-			(void) ldns_dname_cat(hashed_wildcard_name, zone_name);
-
-			if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
-								 hashed_wildcard_name)) {
-				wildcard_covered = true;
-				if (match) {
-					*match = ldns_rr_list_rr(nsecs, i);
-				}
-			}
-			ldns_rdf_deep_free(hashed_wildcard_name);
-		}
-
-		if (! wildcard_covered) {
-			result = LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
-		} else {
-			result = LDNS_STATUS_OK;
-		}
-		ldns_rdf_deep_free(closest_encloser);
-		ldns_rdf_deep_free(wildcard);
-
-	} else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
-		/* section 8.5 */
-		hashed_name = ldns_nsec3_hash_name_frm_nsec3(
-		                   ldns_rr_list_rr(nsecs, 0),
-		                   ldns_rr_owner(rr));
-		(void) ldns_dname_cat(hashed_name, zone_name);
-		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
-			if (ldns_dname_compare(hashed_name,
-			         ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
-			    == 0) {
-				if (!ldns_nsec_bitmap_covers_type(
-					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
-					    packet_qtype)
-				    &&
-				    !ldns_nsec_bitmap_covers_type(
-					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
-					    LDNS_RR_TYPE_CNAME)) {
-					result = LDNS_STATUS_OK;
-					if (match) {
-						*match = ldns_rr_list_rr(nsecs, i);
-					}
-					goto done;
-				}
-			}
-		}
-		result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
-		/* wildcard no data? section 8.7 */
-		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
-				   ldns_rr_owner(rr),
-				   ldns_rr_get_type(rr),
-				   nsecs);
-		if(!closest_encloser) {
-			result = LDNS_STATUS_NSEC3_ERR;
-			goto done;
-		}
-		wildcard = ldns_dname_new_frm_str("*");
-		(void) ldns_dname_cat(wildcard, closest_encloser);
-		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
-			hashed_wildcard_name =
-				ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
-					 wildcard);
-			(void) ldns_dname_cat(hashed_wildcard_name, zone_name);
-
-			if (ldns_dname_compare(hashed_wildcard_name,
-			         ldns_rr_owner(ldns_rr_list_rr(nsecs, i)))
-			    == 0) {
-				if (!ldns_nsec_bitmap_covers_type(
-					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
-					    packet_qtype)
-				    &&
-				    !ldns_nsec_bitmap_covers_type(
-					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
-					    LDNS_RR_TYPE_CNAME)) {
-					result = LDNS_STATUS_OK;
-					if (match) {
-						*match = ldns_rr_list_rr(nsecs, i);
-					}
-				}
-			}
-			ldns_rdf_deep_free(hashed_wildcard_name);
-			if (result == LDNS_STATUS_OK) {
-				break;
-			}
-		}
-		ldns_rdf_deep_free(closest_encloser);
-		ldns_rdf_deep_free(wildcard);
-	} else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
-		/* section 8.6 */
-		/* note: up to XXX this is the same as for 8.5 */
-		hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs,
-														 0),
-											ldns_rr_owner(rr)
-											);
-		(void) ldns_dname_cat(hashed_name, zone_name);
-		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
-			if (ldns_dname_compare(hashed_name,
-							   ldns_rr_owner(ldns_rr_list_rr(nsecs,
-													   i)))
-			    == 0) {
-				if (!ldns_nsec_bitmap_covers_type(
-					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
-					    LDNS_RR_TYPE_DS)
-				    && 
-				    !ldns_nsec_bitmap_covers_type(
-					    ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)),
-					    LDNS_RR_TYPE_CNAME)) {
-					result = LDNS_STATUS_OK;
-					if (match) {
-						*match = ldns_rr_list_rr(nsecs, i);
-					}
-					goto done;
-				}
-			}
-		}
-
-		/* XXX see note above */
-		result = LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
-
-		closest_encloser = ldns_dnssec_nsec3_closest_encloser(
-				   ldns_rr_owner(rr),
-				   ldns_rr_get_type(rr),
-				   nsecs);
-		if(!closest_encloser) {
-			result = LDNS_STATUS_NSEC3_ERR;
-			goto done;
-		}
-		/* Now check if we have a Opt-Out NSEC3 that covers the "next closer"*/
-
-		if (ldns_dname_label_count(closest_encloser) + 1
-		    >= ldns_dname_label_count(ldns_rr_owner(rr))) {
-			
-			/* Query name *is* the "next closer". */
-			hashed_next_closer = hashed_name;
-		} else {
-
-			/* "next closer" has less labels than the query name.
-			 * Create the name and hash it.
-			 */
-			next_closer = ldns_dname_clone_from(
-					ldns_rr_owner(rr),
-					ldns_dname_label_count(ldns_rr_owner(rr))
-					- (ldns_dname_label_count(closest_encloser) + 1)
-					);
-			hashed_next_closer = ldns_nsec3_hash_name_frm_nsec3(
-					ldns_rr_list_rr(nsecs, 0),
-					next_closer
-					);
-			(void) ldns_dname_cat(hashed_next_closer, zone_name);
-		}
-		/* Find the NSEC3 that covers the "next closer" */
-		for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
-			if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
-			                          hashed_next_closer) && 
-				ldns_nsec3_optout(ldns_rr_list_rr(nsecs, i))) {
-
-				result = LDNS_STATUS_OK;
-				if (match) {
-					*match = ldns_rr_list_rr(nsecs, i);
-				}
-				break;
-			}
-		}
-		if (ldns_dname_label_count(closest_encloser) + 1
-		    < ldns_dname_label_count(ldns_rr_owner(rr))) {
-
-			/* "next closer" has less labels than the query name.
-			 * Dispose of the temporary variables that held that name.
-			 */
-			ldns_rdf_deep_free(hashed_next_closer);
-			ldns_rdf_deep_free(next_closer);
-		}
-		ldns_rdf_deep_free(closest_encloser);
-	}
-
- done:
-	ldns_rdf_deep_free(zone_name);
-	return result;
-}
-
-ldns_status
-ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
-						  ldns_rr_list *nsecs,
-						  ldns_rr_list *rrsigs,
-						  ldns_pkt_rcode packet_rcode,
-						  ldns_rr_type packet_qtype,
-						  bool packet_nodata)
-{
-	return ldns_dnssec_verify_denial_nsec3_match(
-				rr, nsecs, rrsigs, packet_rcode,
-				packet_qtype, packet_nodata, NULL
-	       );
-}
-
-#ifdef USE_GOST
-EVP_PKEY*
-ldns_gost2pkey_raw(unsigned char* key, size_t keylen)
-{
-	/* prefix header for X509 encoding */
-	uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 
-		0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 
-		0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 
-		0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
-	unsigned char encoded[37+64];
-	const unsigned char* pp;
-	if(keylen != 64) {
-		/* key wrong size */
-		return NULL;
-	}
-
-	/* create evp_key */
-	memmove(encoded, asn, 37);
-	memmove(encoded+37, key, 64);
-	pp = (unsigned char*)&encoded[0];
-
-	return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
-}
-
-static ldns_status
-ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen, 
-	ldns_buffer* rrset, unsigned char* key, size_t keylen)
-{
-	EVP_PKEY *evp_key;
-	ldns_status result;
-
-	(void) ldns_key_EVP_load_gost_id();
-	evp_key = ldns_gost2pkey_raw(key, keylen);
-	if(!evp_key) {
-		/* could not convert key */
-		return LDNS_STATUS_CRYPTO_BOGUS;
-	}
-
-	/* verify signature */
-	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, 
-		evp_key, EVP_get_digestbyname("md_gost94"));
-	EVP_PKEY_free(evp_key);
-
-	return result;
-}
-#endif
-
-#ifdef USE_ECDSA
-EVP_PKEY*
-ldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
-{
-	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
-        const unsigned char* pp = buf;
-        EVP_PKEY *evp_key;
-        EC_KEY *ec;
-	/* check length, which uncompressed must be 2 bignums */
-        if(algo == LDNS_ECDSAP256SHA256) {
-		if(keylen != 2*256/8) return NULL;
-                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
-        } else if(algo == LDNS_ECDSAP384SHA384) {
-		if(keylen != 2*384/8) return NULL;
-                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
-        } else    ec = NULL;
-        if(!ec) return NULL;
-	if(keylen+1 > sizeof(buf))
-		return NULL; /* sanity check */
-	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
-	 * of openssl) for uncompressed data */
-	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
-	memmove(buf+1, key, keylen);
-        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-        evp_key = EVP_PKEY_new();
-        if(!evp_key) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
-		EVP_PKEY_free(evp_key);
-		EC_KEY_free(ec);
-		return NULL;
-	}
-        return evp_key;
-}
-
-static ldns_status
-ldns_verify_rrsig_ecdsa_raw(unsigned char* sig, size_t siglen, 
-	ldns_buffer* rrset, unsigned char* key, size_t keylen, uint8_t algo)
-{
-        EVP_PKEY *evp_key;
-        ldns_status result;
-        const EVP_MD *d;
-
-        evp_key = ldns_ecdsa2pkey_raw(key, keylen, algo);
-        if(!evp_key) {
-		/* could not convert key */
-		return LDNS_STATUS_CRYPTO_BOGUS;
-        }
-        if(algo == LDNS_ECDSAP256SHA256)
-                d = EVP_sha256();
-        else    d = EVP_sha384(); /* LDNS_ECDSAP384SHA384 */
-	result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset, evp_key, d);
-	EVP_PKEY_free(evp_key);
-	return result;
-}
-#endif
-
-ldns_status
-ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf, 
-					 ldns_buffer *key_buf, uint8_t algo)
-{
-	return ldns_verify_rrsig_buffers_raw(
-			 (unsigned char*)ldns_buffer_begin(rawsig_buf),
-			 ldns_buffer_position(rawsig_buf),
-			 verify_buf,
-			 (unsigned char*)ldns_buffer_begin(key_buf), 
-			 ldns_buffer_position(key_buf), algo);
-}
-
-ldns_status
-ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
-						ldns_buffer *verify_buf, unsigned char* key, size_t keylen, 
-						uint8_t algo)
-{
-	/* check for right key */
-	switch(algo) {
-	case LDNS_DSA:
-	case LDNS_DSA_NSEC3:
-		return ldns_verify_rrsig_dsa_raw(sig,
-								   siglen,
-								   verify_buf,
-								   key,
-								   keylen);
-		break;
-	case LDNS_RSASHA1:
-	case LDNS_RSASHA1_NSEC3:
-		return ldns_verify_rrsig_rsasha1_raw(sig,
-									  siglen,
-									  verify_buf,
-									  key,
-									  keylen);
-		break;
-#ifdef USE_SHA2
-	case LDNS_RSASHA256:
-		return ldns_verify_rrsig_rsasha256_raw(sig,
-									    siglen,
-									    verify_buf,
-									    key,
-									    keylen);
-		break;
-	case LDNS_RSASHA512:
-		return ldns_verify_rrsig_rsasha512_raw(sig,
-									    siglen,
-									    verify_buf,
-									    key,
-									    keylen);
-		break;
-#endif
-#ifdef USE_GOST
-	case LDNS_ECC_GOST:
-		return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
-			key, keylen);
-		break;
-#endif
-#ifdef USE_ECDSA
-        case LDNS_ECDSAP256SHA256:
-        case LDNS_ECDSAP384SHA384:
-		return ldns_verify_rrsig_ecdsa_raw(sig, siglen, verify_buf,
-			key, keylen, algo);
-		break;
-#endif
-	case LDNS_RSAMD5:
-		return ldns_verify_rrsig_rsamd5_raw(sig,
-									 siglen,
-									 verify_buf,
-									 key,
-									 keylen);
-		break;
-	default:
-		/* do you know this alg?! */
-		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
-	}
-}
-
-
-/**
- * Reset the ttl in the rrset with the orig_ttl from the sig 
- * and update owner name if it was wildcard 
- * Also canonicalizes the rrset.
- * @param rrset: rrset to modify
- * @param sig: signature to take TTL and wildcard values from
- */
-static void
-ldns_rrset_use_signature_ttl(ldns_rr_list* rrset_clone, ldns_rr* rrsig)
-{
-	uint32_t orig_ttl;
-	uint16_t i;
-	uint8_t label_count;
-	ldns_rdf *wildcard_name;
-	ldns_rdf *wildcard_chopped;
-	ldns_rdf *wildcard_chopped_tmp;
-	
-	if ((rrsig == NULL) || ldns_rr_rd_count(rrsig) < 4) {
-		return;
-	}
-
-	orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
-	label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
-
-	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
-		if (label_count < 
-		    ldns_dname_label_count(
-			   ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
-			(void) ldns_str2rdf_dname(&wildcard_name, "*");
-			wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(
-				ldns_rr_list_rr(rrset_clone, i)));
-			while (label_count < ldns_dname_label_count(wildcard_chopped)) {
-				wildcard_chopped_tmp = ldns_dname_left_chop(
-					wildcard_chopped);
-				ldns_rdf_deep_free(wildcard_chopped);
-				wildcard_chopped = wildcard_chopped_tmp;
-			}
-			(void) ldns_dname_cat(wildcard_name, wildcard_chopped);
-			ldns_rdf_deep_free(wildcard_chopped);
-			ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(
-				rrset_clone, i)));
-			ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), 
-				wildcard_name);
-		}
-		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
-		/* convert to lowercase */
-		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
-	}
-}
-
-/**
- * Make raw signature buffer out of rrsig
- * @param rawsig_buf: raw signature buffer for result
- * @param rrsig: signature to convert
- * @return OK or more specific error.
- */
-static ldns_status
-ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
-{
-	uint8_t sig_algo;
-       
-	if (rrsig == NULL) {
-		return LDNS_STATUS_CRYPTO_NO_RRSIG;
-	}
-	if (ldns_rr_rdf(rrsig, 1) == NULL) {
-		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
-	}
-	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
-	/* check for known and implemented algo's now (otherwise 
-	 * the function could return a wrong error
-	 */
-	/* create a buffer with signature rdata */
-	/* for some algorithms we need other data than for others... */
-	/* (the DSA API wants DER encoding for instance) */
-
-	switch(sig_algo) {
-	case LDNS_RSAMD5:
-	case LDNS_RSASHA1:
-	case LDNS_RSASHA1_NSEC3:
-#ifdef USE_SHA2
-	case LDNS_RSASHA256:
-	case LDNS_RSASHA512:
-#endif
-#ifdef USE_GOST
-	case LDNS_ECC_GOST:
-#endif
-		if (ldns_rr_rdf(rrsig, 8) == NULL) {
-			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
-		}
-		if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8))
-			       	!= LDNS_STATUS_OK) {
-			return LDNS_STATUS_MEM_ERR;
-		}
-		break;
-	case LDNS_DSA:
-	case LDNS_DSA_NSEC3:
-		/* EVP takes rfc2459 format, which is a tad longer than dns format */
-		if (ldns_rr_rdf(rrsig, 8) == NULL) {
-			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
-		}
-		if (ldns_convert_dsa_rrsig_rdf2asn1(
-					rawsig_buf, ldns_rr_rdf(rrsig, 8)) 
-				!= LDNS_STATUS_OK) {
-			/*
-			  if (ldns_rdf2buffer_wire(rawsig_buf,
-			  ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
-			*/
-			return LDNS_STATUS_MEM_ERR;
-		}
-		break;
-#ifdef USE_ECDSA
-        case LDNS_ECDSAP256SHA256:
-        case LDNS_ECDSAP384SHA384:
-                /* EVP produces an ASN prefix on the signature, which is
-                 * not used in the DNS */
-		if (ldns_rr_rdf(rrsig, 8) == NULL) {
-			return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
-		}
-		if (ldns_convert_ecdsa_rrsig_rdf2asn1(
-					rawsig_buf, ldns_rr_rdf(rrsig, 8))
-				!= LDNS_STATUS_OK) {
-			return LDNS_STATUS_MEM_ERR;
-                }
-                break;
-#endif
-	case LDNS_DH:
-	case LDNS_ECC:
-	case LDNS_INDIRECT:
-		return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
-	default:
-		return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
-	}
-	return LDNS_STATUS_OK;
-}
-
-/**
- * Check RRSIG timestamps against the given 'now' time.
- * @param rrsig: signature to check.
- * @param now: the current time in seconds epoch.
- * @return status code LDNS_STATUS_OK if all is fine.
- */
-static ldns_status
-ldns_rrsig_check_timestamps(ldns_rr* rrsig, time_t now)
-{
-	int32_t inception, expiration;
-	
-	/* check the signature time stamps */
-	inception = (int32_t)ldns_rdf2native_time_t(
-		ldns_rr_rrsig_inception(rrsig));
-	expiration = (int32_t)ldns_rdf2native_time_t(
-		ldns_rr_rrsig_expiration(rrsig));
-
-	if (expiration - inception < 0) {
-		/* bad sig, expiration before inception?? Tsssg */
-		return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
-	}
-	if (((int32_t) now) - inception < 0) {
-		/* bad sig, inception date has not yet come to pass */
-		return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
-	}
-	if (expiration - ((int32_t) now) < 0) {
-		/* bad sig, expiration date has passed */
-		return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
-	}
-	return LDNS_STATUS_OK;
-}
-
-/**
- * Prepare for verification.
- * @param rawsig_buf: raw signature buffer made ready.
- * @param verify_buf: data for verification buffer made ready.
- * @param rrset_clone: made ready.
- * @param rrsig: signature to prepare for.
- * @return LDNS_STATUS_OK is all went well. Otherwise specific error.
- */
-static ldns_status
-ldns_prepare_for_verify(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
-	ldns_rr_list* rrset_clone, ldns_rr* rrsig)
-{
-	ldns_status result;
-
-	/* canonicalize the sig */
-	ldns_dname2canonical(ldns_rr_owner(rrsig));
-	
-	/* check if the typecovered is equal to the type checked */
-	if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
-	    ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0)))
-		return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
-	
-	/* create a buffer with b64 signature rdata */
-	result = ldns_rrsig2rawsig_buffer(rawsig_buf, rrsig);
-	if(result != LDNS_STATUS_OK)
-		return result;
-
-	/* use TTL from signature. Use wildcard names for wildcards */
-	/* also canonicalizes rrset_clone */
-	ldns_rrset_use_signature_ttl(rrset_clone, rrsig);
-
-	/* sort the rrset in canonical order  */
-	ldns_rr_list_sort(rrset_clone);
-
-	/* put the signature rr (without the b64) to the verify_buf */
-	if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK)
-		return LDNS_STATUS_MEM_ERR;
-
-	/* add the rrset in verify_buf */
-	if(ldns_rr_list2buffer_wire(verify_buf, rrset_clone) 
-		!= LDNS_STATUS_OK)
-		return LDNS_STATUS_MEM_ERR;
-
-	return LDNS_STATUS_OK;
-}
-
-/**
- * Check if a key matches a signature.
- * Checks keytag, sigalgo and signature.
- * @param rawsig_buf: raw signature buffer for verify
- * @param verify_buf: raw data buffer for verify
- * @param rrsig: the rrsig
- * @param key: key to attempt.
- * @return LDNS_STATUS_OK if OK, else some specific error.
- */
-static ldns_status
-ldns_verify_test_sig_key(ldns_buffer* rawsig_buf, ldns_buffer* verify_buf, 
-	ldns_rr* rrsig, ldns_rr* key)
-{
-	uint8_t sig_algo;
-       
-	if (rrsig == NULL) {
-		return LDNS_STATUS_CRYPTO_NO_RRSIG;
-	}
-	if (ldns_rr_rdf(rrsig, 1) == NULL) {
-		return LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG;
-	}
-	sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
-
-	/* before anything, check if the keytags match */
-	if (ldns_calc_keytag(key)
-	    ==
-	    ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
-	    ) {
-		ldns_buffer* key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-		ldns_status result = LDNS_STATUS_ERR;
-
-		/* put the key-data in a buffer, that's the third rdf, with
-		 * the base64 encoded key data */
-		if (ldns_rr_rdf(key, 3) == NULL) {
-			ldns_buffer_free(key_buf);
-			return LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
-		}
-		if (ldns_rdf2buffer_wire(key_buf, ldns_rr_rdf(key, 3))
-			       	!= LDNS_STATUS_OK) {
-			ldns_buffer_free(key_buf); 
-			/* returning is bad might screw up
-			   good keys later in the list
-			   what to do? */
-			return LDNS_STATUS_ERR;
-		}
-
-		if (ldns_rr_rdf(key, 2) == NULL) {
-			result = LDNS_STATUS_MISSING_RDATA_FIELDS_KEY;
-		}
-		else if (sig_algo == ldns_rdf2native_int8(
-					ldns_rr_rdf(key, 2))) {
-			result = ldns_verify_rrsig_buffers(rawsig_buf, 
-				verify_buf, key_buf, sig_algo);
-		} else {
-			/* No keys with the corresponding algorithm are found */
-			result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
-		}
-
-		ldns_buffer_free(key_buf); 
-		return result;
-	}
-	else {
-		/* No keys with the corresponding keytag are found */
-		return LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
-	}
-}
-
-/* 
- * to verify:
- * - create the wire fmt of the b64 key rdata
- * - create the wire fmt of the sorted rrset
- * - create the wire fmt of the b64 sig rdata
- * - create the wire fmt of the sig without the b64 rdata
- * - cat the sig data (without b64 rdata) to the rrset
- * - verify the rrset+sig, with the b64 data and the b64 key data
- */
-ldns_status
-ldns_verify_rrsig_keylist_time(
-		ldns_rr_list *rrset,
-		ldns_rr *rrsig,
-		const ldns_rr_list *keys, 
-		time_t check_time,
-		ldns_rr_list *good_keys)
-{
-	ldns_status result;
-	ldns_rr_list *valid = ldns_rr_list_new();
-	if (!valid)
-		return LDNS_STATUS_MEM_ERR;
-
-	result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
-	if(result != LDNS_STATUS_OK) {
-		ldns_rr_list_free(valid); 
-		return result;
-	}
-
-	/* check timestamps last; its OK except time */
-	result = ldns_rrsig_check_timestamps(rrsig, check_time);
-	if(result != LDNS_STATUS_OK) {
-		ldns_rr_list_free(valid); 
-		return result;
-	}
-
-	ldns_rr_list_cat(good_keys, valid);
-	ldns_rr_list_free(valid);
-	return LDNS_STATUS_OK;
-}
-
-/* 
- * to verify:
- * - create the wire fmt of the b64 key rdata
- * - create the wire fmt of the sorted rrset
- * - create the wire fmt of the b64 sig rdata
- * - create the wire fmt of the sig without the b64 rdata
- * - cat the sig data (without b64 rdata) to the rrset
- * - verify the rrset+sig, with the b64 data and the b64 key data
- */
-ldns_status
-ldns_verify_rrsig_keylist(ldns_rr_list *rrset,
-					 ldns_rr *rrsig,
-					 const ldns_rr_list *keys, 
-					 ldns_rr_list *good_keys)
-{
-	return ldns_verify_rrsig_keylist_time(
-			rrset, rrsig, keys, ldns_time(NULL), good_keys);
-}
-
-ldns_status
-ldns_verify_rrsig_keylist_notime(ldns_rr_list *rrset,
-					 ldns_rr *rrsig,
-					 const ldns_rr_list *keys, 
-					 ldns_rr_list *good_keys)
-{
-	ldns_buffer *rawsig_buf;
-	ldns_buffer *verify_buf;
-	uint16_t i;
-	ldns_status result, status;
-	ldns_rr_list *rrset_clone;
-	ldns_rr_list *validkeys;
-
-	if (!rrset) {
-		return LDNS_STATUS_ERR;
-	}
-
-	validkeys = ldns_rr_list_new();
-	if (!validkeys) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	
-	/* clone the rrset so that we can fiddle with it */
-	rrset_clone = ldns_rr_list_clone(rrset);
-
-	/* create the buffers which will certainly hold the raw data */
-	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-
-	result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 
-		rrset_clone, rrsig);
-	if(result != LDNS_STATUS_OK) {
-		ldns_buffer_free(verify_buf);
-		ldns_buffer_free(rawsig_buf);
-		ldns_rr_list_deep_free(rrset_clone);
-		ldns_rr_list_free(validkeys);
-		return result;
-	}
-
-	result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
-	for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
-		status = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
-			rrsig, ldns_rr_list_rr(keys, i));
-		if (status == LDNS_STATUS_OK) {
-			/* one of the keys has matched, don't break
-			 * here, instead put the 'winning' key in
-			 * the validkey list and return the list 
-			 * later */
-			if (!ldns_rr_list_push_rr(validkeys, 
-				ldns_rr_list_rr(keys,i))) {
-				/* couldn't push the key?? */
-				ldns_buffer_free(rawsig_buf);
-				ldns_buffer_free(verify_buf);
-				ldns_rr_list_deep_free(rrset_clone);
-				ldns_rr_list_free(validkeys);
-				return LDNS_STATUS_MEM_ERR;
-			}
-
-			result = status;
-		}
-
-		if (result == LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY) {
-			result = status;
-		}
-	}
-
-	/* no longer needed */
-	ldns_rr_list_deep_free(rrset_clone);
-	ldns_buffer_free(rawsig_buf);
-	ldns_buffer_free(verify_buf);
-
-	if (ldns_rr_list_rr_count(validkeys) == 0) {
-		/* no keys were added, return last error */
-		ldns_rr_list_free(validkeys); 
-		return result;
-	}
-
-	/* do not check timestamps */
-
-	ldns_rr_list_cat(good_keys, validkeys);
-	ldns_rr_list_free(validkeys);
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_verify_rrsig_time(
-		ldns_rr_list *rrset, 
-		ldns_rr *rrsig, 
-		ldns_rr *key, 
-		time_t check_time)
-{
-	ldns_buffer *rawsig_buf;
-	ldns_buffer *verify_buf;
-	ldns_status result;
-	ldns_rr_list *rrset_clone;
-
-	if (!rrset) {
-		return LDNS_STATUS_NO_DATA;
-	}
-	/* clone the rrset so that we can fiddle with it */
-	rrset_clone = ldns_rr_list_clone(rrset);
-	/* create the buffers which will certainly hold the raw data */
-	rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	verify_buf  = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-
-	result = ldns_prepare_for_verify(rawsig_buf, verify_buf, 
-		rrset_clone, rrsig);
-	if(result != LDNS_STATUS_OK) {
-		ldns_rr_list_deep_free(rrset_clone);
-		ldns_buffer_free(rawsig_buf);
-		ldns_buffer_free(verify_buf);
-		return result;
-	}
-	result = ldns_verify_test_sig_key(rawsig_buf, verify_buf, 
-		rrsig, key);
-	/* no longer needed */
-	ldns_rr_list_deep_free(rrset_clone);
-	ldns_buffer_free(rawsig_buf);
-	ldns_buffer_free(verify_buf);
-
-	/* check timestamp last, apart from time its OK */
-	if(result == LDNS_STATUS_OK)
-		result = ldns_rrsig_check_timestamps(rrsig, check_time);
-
-	return result;
-}
-
-ldns_status
-ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
-{
-	return ldns_verify_rrsig_time(rrset, rrsig, key, ldns_time(NULL));
-}
-
-
-ldns_status
-ldns_verify_rrsig_evp(ldns_buffer *sig,
-				  ldns_buffer *rrset,
-				  EVP_PKEY *key,
-				  const EVP_MD *digest_type)
-{
-	return ldns_verify_rrsig_evp_raw(
-			 (unsigned char*)ldns_buffer_begin(sig),
-			 ldns_buffer_position(sig),
-			 rrset,
-			 key,
-			 digest_type);
-}
-
-ldns_status
-ldns_verify_rrsig_evp_raw(unsigned char *sig, size_t siglen, 
-					 ldns_buffer *rrset, EVP_PKEY *key, const EVP_MD *digest_type)
-{
-	EVP_MD_CTX ctx;
-	int res;
-
-	EVP_MD_CTX_init(&ctx);
-	
-	EVP_VerifyInit(&ctx, digest_type);
-	EVP_VerifyUpdate(&ctx,
-				  ldns_buffer_begin(rrset),
-				  ldns_buffer_position(rrset));
-	res = EVP_VerifyFinal(&ctx, sig, (unsigned int) siglen, key);
-	
-	EVP_MD_CTX_cleanup(&ctx);
-	
-	if (res == 1) {
-		return LDNS_STATUS_OK;
-	} else if (res == 0) {
-		return LDNS_STATUS_CRYPTO_BOGUS;
-	}
-	/* TODO how to communicate internal SSL error?
-	   let caller use ssl's get_error() */
-	return LDNS_STATUS_SSL_ERR;
-}
-
-ldns_status
-ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
-{
-	return ldns_verify_rrsig_dsa_raw(
-			 (unsigned char*) ldns_buffer_begin(sig),
-			 ldns_buffer_position(sig),
-			 rrset,
-			 (unsigned char*) ldns_buffer_begin(key),
-			 ldns_buffer_position(key));
-}
-
-ldns_status
-ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
-{
-	return ldns_verify_rrsig_rsasha1_raw(
-			 (unsigned char*)ldns_buffer_begin(sig),
-			 ldns_buffer_position(sig),
-			 rrset,
-			 (unsigned char*) ldns_buffer_begin(key),
-			 ldns_buffer_position(key));
-}
-
-ldns_status
-ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
-{
-	return ldns_verify_rrsig_rsamd5_raw(
-			 (unsigned char*)ldns_buffer_begin(sig),
-			 ldns_buffer_position(sig),
-			 rrset,
-			 (unsigned char*) ldns_buffer_begin(key),
-			 ldns_buffer_position(key));
-}
-
-ldns_status
-ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
-					 ldns_buffer* rrset, unsigned char* key, size_t keylen)
-{
-	EVP_PKEY *evp_key;
-	ldns_status result;
-
-	evp_key = EVP_PKEY_new();
-	if (EVP_PKEY_assign_DSA(evp_key, ldns_key_buf2dsa_raw(key, keylen))) {
-		result = ldns_verify_rrsig_evp_raw(sig,
-								siglen,
-								rrset,
-								evp_key,
-								EVP_dss1());
-	} else {
-		result = LDNS_STATUS_SSL_ERR;
-	}
-	EVP_PKEY_free(evp_key);
-	return result;
-
-}
-
-ldns_status
-ldns_verify_rrsig_rsasha1_raw(unsigned char* sig, size_t siglen,
-						ldns_buffer* rrset, unsigned char* key, size_t keylen)
-{
-	EVP_PKEY *evp_key;
-	ldns_status result;
-
-	evp_key = EVP_PKEY_new();
-	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
-		result = ldns_verify_rrsig_evp_raw(sig,
-								siglen,
-								rrset,
-								evp_key,
-								EVP_sha1());
-	} else {
-		result = LDNS_STATUS_SSL_ERR;
-	}
-	EVP_PKEY_free(evp_key);
-
-	return result;
-}
-
-ldns_status
-ldns_verify_rrsig_rsasha256_raw(unsigned char* sig,
-						  size_t siglen,
-						  ldns_buffer* rrset,
-						  unsigned char* key,
-						  size_t keylen)
-{
-#ifdef USE_SHA2
-	EVP_PKEY *evp_key;
-	ldns_status result;
-
-	evp_key = EVP_PKEY_new();
-	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
-		result = ldns_verify_rrsig_evp_raw(sig,
-								siglen,
-								rrset,
-								evp_key,
-								EVP_sha256());
-	} else {
-		result = LDNS_STATUS_SSL_ERR;
-	}
-	EVP_PKEY_free(evp_key);
-
-	return result;
-#else
-	/* touch these to prevent compiler warnings */
-	(void) sig;
-	(void) siglen;
-	(void) rrset;
-	(void) key;
-	(void) keylen;
-	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
-#endif
-}
-
-ldns_status
-ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
-						  size_t siglen,
-						  ldns_buffer* rrset,
-						  unsigned char* key,
-						  size_t keylen)
-{
-#ifdef USE_SHA2
-	EVP_PKEY *evp_key;
-	ldns_status result;
-
-	evp_key = EVP_PKEY_new();
-	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
-		result = ldns_verify_rrsig_evp_raw(sig,
-								siglen,
-								rrset,
-								evp_key,
-								EVP_sha512());
-	} else {
-		result = LDNS_STATUS_SSL_ERR;
-	}
-	EVP_PKEY_free(evp_key);
-
-	return result;
-#else
-	/* touch these to prevent compiler warnings */
-	(void) sig;
-	(void) siglen;
-	(void) rrset;
-	(void) key;
-	(void) keylen;
-	return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
-#endif
-}
-
-
-ldns_status
-ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
-					    size_t siglen,
-					    ldns_buffer* rrset,
-					    unsigned char* key,
-					    size_t keylen)
-{
-	EVP_PKEY *evp_key;
-	ldns_status result;
-
-	evp_key = EVP_PKEY_new();
-	if (EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen))) {
-		result = ldns_verify_rrsig_evp_raw(sig,
-								siglen,
-								rrset,
-								evp_key,
-								EVP_md5());
-	} else {
-		result = LDNS_STATUS_SSL_ERR;
-	}
-	EVP_PKEY_free(evp_key);
-
-	return result;
-}
-
-#endif
diff --git a/src/ldns/dnssec_zone.c b/src/ldns/dnssec_zone.c
deleted file mode 100644
index 0fec48c..0000000
--- a/src/ldns/dnssec_zone.c
+++ /dev/null
@@ -1,1192 +0,0 @@
-/*
- * special zone file structures and functions for better dnssec handling
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-ldns_dnssec_rrs *
-ldns_dnssec_rrs_new(void)
-{
-	ldns_dnssec_rrs *new_rrs;
-	new_rrs = LDNS_MALLOC(ldns_dnssec_rrs);
-        if(!new_rrs) return NULL;
-	new_rrs->rr = NULL;
-	new_rrs->next = NULL;
-	return new_rrs;
-}
-
-INLINE void
-ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep)
-{
-	ldns_dnssec_rrs *next;
-	while (rrs) {
-		next = rrs->next;
-		if (deep) {
-			ldns_rr_free(rrs->rr);
-		}
-		LDNS_FREE(rrs);
-		rrs = next;
-	}
-}
-
-void
-ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs)
-{
-	ldns_dnssec_rrs_free_internal(rrs, 0);
-}
-
-void
-ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs)
-{
-	ldns_dnssec_rrs_free_internal(rrs, 1);
-}
-
-ldns_status
-ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
-{
-	int cmp;
-	ldns_dnssec_rrs *new_rrs;
-	if (!rrs || !rr) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* this could be done more efficiently; name and type should already
-	   be equal */
-	cmp = ldns_rr_compare(rrs->rr, rr);
-	if (cmp < 0) {
-		if (rrs->next) {
-			return ldns_dnssec_rrs_add_rr(rrs->next, rr);
-		} else {
-			new_rrs = ldns_dnssec_rrs_new();
-			new_rrs->rr = rr;
-			rrs->next = new_rrs;
-		}
-	} else if (cmp > 0) {
-		/* put the current old rr in the new next, put the new
-		   rr in the current container */
-		new_rrs = ldns_dnssec_rrs_new();
-		new_rrs->rr = rrs->rr;
-		new_rrs->next = rrs->next;
-		rrs->rr = rr;
-		rrs->next = new_rrs;
-	}
-	/* Silently ignore equal rr's */
-	return LDNS_STATUS_OK;
-}
-
-void
-ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt,
-	       ldns_dnssec_rrs *rrs)
-{
-	if (!rrs) {
-		if ((fmt->flags & LDNS_COMMENT_LAYOUT))
-			fprintf(out, "; <void>");
-	} else {
-		if (rrs->rr) {
-			ldns_rr_print_fmt(out, fmt, rrs->rr);
-		}
-		if (rrs->next) {
-			ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next);
-		}
-	}
-}
-
-void
-ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs)
-{
-	ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs);
-}
-
-
-ldns_dnssec_rrsets *
-ldns_dnssec_rrsets_new(void)
-{
-	ldns_dnssec_rrsets *new_rrsets;
-	new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets);
-        if(!new_rrsets) return NULL;
-	new_rrsets->rrs = NULL;
-	new_rrsets->type = 0;
-	new_rrsets->signatures = NULL;
-	new_rrsets->next = NULL;
-	return new_rrsets;
-}
-
-INLINE void
-ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep)
-{
-	if (rrsets) {
-		if (rrsets->rrs) {
-			ldns_dnssec_rrs_free_internal(rrsets->rrs, deep);
-		}
-		if (rrsets->next) {
-			ldns_dnssec_rrsets_free_internal(rrsets->next, deep);
-		}
-		if (rrsets->signatures) {
-			ldns_dnssec_rrs_free_internal(rrsets->signatures, deep);
-		}
-		LDNS_FREE(rrsets);
-	}
-}
-
-void
-ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets)
-{
-	ldns_dnssec_rrsets_free_internal(rrsets, 0);
-}
-
-void
-ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets)
-{
-	ldns_dnssec_rrsets_free_internal(rrsets, 1);
-}
-
-ldns_rr_type
-ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets)
-{
-	if (rrsets) {
-		return rrsets->type;
-	} else {
-		return 0;
-	}
-}
-
-ldns_status
-ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets,
-					   ldns_rr_type type)
-{
-	if (rrsets) {
-		rrsets->type = type;
-		return LDNS_STATUS_OK;
-	}
-	return LDNS_STATUS_ERR;
-}
-
-static ldns_dnssec_rrsets *
-ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr)
-{
-	ldns_dnssec_rrsets *new_rrsets;
-	ldns_rr_type rr_type;
-	bool rrsig;
-
-	new_rrsets = ldns_dnssec_rrsets_new();
-	rr_type = ldns_rr_get_type(rr);
-	if (rr_type == LDNS_RR_TYPE_RRSIG) {
-		rrsig = true;
-		rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
-	} else {
-		rrsig = false;
-	}
-	if (!rrsig) {
-		new_rrsets->rrs = ldns_dnssec_rrs_new();
-		new_rrsets->rrs->rr = rr;
-	} else {
-		new_rrsets->signatures = ldns_dnssec_rrs_new();
-		new_rrsets->signatures->rr = rr;
-	}
-	new_rrsets->type = rr_type;
-	return new_rrsets;
-}
-
-ldns_status
-ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr)
-{
-	ldns_dnssec_rrsets *new_rrsets;
-	ldns_rr_type rr_type;
-	bool rrsig = false;
-	ldns_status result = LDNS_STATUS_OK;
-
-	if (!rrsets || !rr) {
-		return LDNS_STATUS_ERR;
-	}
-
-	rr_type = ldns_rr_get_type(rr);
-
-	if (rr_type == LDNS_RR_TYPE_RRSIG) {
-		rrsig = true;
-		rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
-	}
-
-	if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) {
-		if (!rrsig) {
-			rrsets->rrs = ldns_dnssec_rrs_new();
-			rrsets->rrs->rr = rr;
-			rrsets->type = rr_type;
-		} else {
-			rrsets->signatures = ldns_dnssec_rrs_new();
-			rrsets->signatures->rr = rr;
-			rrsets->type = rr_type;
-		}
-		return LDNS_STATUS_OK;
-	}
-
-	if (rr_type > ldns_dnssec_rrsets_type(rrsets)) {
-		if (rrsets->next) {
-			result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr);
-		} else {
-			new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr);
-			rrsets->next = new_rrsets;
-		}
-	} else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) {
-		/* move the current one into the new next, 
-		   replace field of current with data from new rr */
-		new_rrsets = ldns_dnssec_rrsets_new();
-		new_rrsets->rrs = rrsets->rrs;
-		new_rrsets->type = rrsets->type;
-		new_rrsets->signatures = rrsets->signatures;
-		new_rrsets->next = rrsets->next;
-		if (!rrsig) {
-			rrsets->rrs = ldns_dnssec_rrs_new();
-			rrsets->rrs->rr = rr;
-			rrsets->signatures = NULL;
-		} else {
-			rrsets->rrs = NULL;
-			rrsets->signatures = ldns_dnssec_rrs_new();
-			rrsets->signatures->rr = rr;
-		}
-		rrsets->type = rr_type;
-		rrsets->next = new_rrsets;
-	} else {
-		/* equal, add to current rrsets */
-		if (rrsig) {
-			if (rrsets->signatures) {
-				result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr);
-			} else {
-				rrsets->signatures = ldns_dnssec_rrs_new();
-				rrsets->signatures->rr = rr;
-			}
-		} else {
-			if (rrsets->rrs) {
-				result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr);
-			} else {
-				rrsets->rrs = ldns_dnssec_rrs_new();
-				rrsets->rrs->rr = rr;
-			}
-		}
-	}
-
-	return result;
-}
-
-static void
-ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
-		ldns_dnssec_rrsets *rrsets,
-		bool follow,
-		bool show_soa)
-{
-	if (!rrsets) {
-		if ((fmt->flags & LDNS_COMMENT_LAYOUT))
-			fprintf(out, "; <void>\n");
-	} else {
-		if (rrsets->rrs &&
-		    (show_soa ||
-			ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA
-		    )
-		   ) {
-			ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs);
-			if (rrsets->signatures) {
-				ldns_dnssec_rrs_print_fmt(out, fmt, 
-						rrsets->signatures);
-			}
-		}
-		if (follow && rrsets->next) {
-			ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 
-					rrsets->next, follow, show_soa);
-		}
-	}
-}
-
-
-void
-ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt,
-		ldns_dnssec_rrsets *rrsets, 
-		bool follow)
-{
-	ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true);
-}
-
-void
-ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow)
-{
-	ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default, 
-			rrsets, follow);
-}
-
-ldns_dnssec_name *
-ldns_dnssec_name_new(void)
-{
-	ldns_dnssec_name *new_name;
-
-	new_name = LDNS_CALLOC(ldns_dnssec_name, 1);
-	if (!new_name) {
-		return NULL;
-	}
-	/*
-	 * not needed anymore because CALLOC initalizes everything to zero.
-
-	new_name->name = NULL;
-	new_name->rrsets = NULL;
-	new_name->name_alloced = false;
-	new_name->nsec = NULL;
-	new_name->nsec_signatures = NULL;
-
-	new_name->is_glue = false;
-	new_name->hashed_name = NULL;
-
-	 */
-	return new_name;
-}
-
-ldns_dnssec_name *
-ldns_dnssec_name_new_frm_rr(ldns_rr *rr)
-{
-	ldns_dnssec_name *new_name = ldns_dnssec_name_new();
-
-	new_name->name = ldns_rr_owner(rr);
-	if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) {
-		ldns_dnssec_name_free(new_name);
-		return NULL;
-	}
-
-	return new_name;
-}
-
-INLINE void
-ldns_dnssec_name_free_internal(ldns_dnssec_name *name,
-                               int deep)
-{
-	if (name) {
-		if (name->name_alloced) {
-			ldns_rdf_deep_free(name->name);
-		}
-		if (name->rrsets) {
-			ldns_dnssec_rrsets_free_internal(name->rrsets, deep);
-		}
-		if (name->nsec && deep) {
-			ldns_rr_free(name->nsec);
-		}
-		if (name->nsec_signatures) {
-			ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep);
-		}
-		if (name->hashed_name) {
-			if (deep) {
-				ldns_rdf_deep_free(name->hashed_name);
-			}
-		}
-		LDNS_FREE(name);
-	}
-}
-
-void
-ldns_dnssec_name_free(ldns_dnssec_name *name)
-{
-  ldns_dnssec_name_free_internal(name, 0);
-}
-
-void
-ldns_dnssec_name_deep_free(ldns_dnssec_name *name)
-{
-  ldns_dnssec_name_free_internal(name, 1);
-}
-
-ldns_rdf *
-ldns_dnssec_name_name(ldns_dnssec_name *name)
-{
-	if (name) {
-		return name->name;
-	}
-	return NULL;
-}
-
-bool
-ldns_dnssec_name_is_glue(ldns_dnssec_name *name)
-{
-	if (name) {
-		return name->is_glue;
-	}
-	return false;
-}
-
-void
-ldns_dnssec_name_set_name(ldns_dnssec_name *rrset,
-					 ldns_rdf *dname)
-{
-	if (rrset && dname) {
-		rrset->name = dname;
-	}
-}
-
-
-void
-ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec)
-{
-	if (rrset && nsec) {
-		rrset->nsec = nsec;
-	}
-}
-
-int
-ldns_dnssec_name_cmp(const void *a, const void *b)
-{
-	ldns_dnssec_name *na = (ldns_dnssec_name *) a;
-	ldns_dnssec_name *nb = (ldns_dnssec_name *) b;
-
-	if (na && nb) {
-		return ldns_dname_compare(ldns_dnssec_name_name(na),
-							 ldns_dnssec_name_name(nb));
-	} else if (na) {
-		return 1;
-	} else if (nb) {
-		return -1;
-	} else {
-		return 0;
-	}
-}
-
-ldns_status
-ldns_dnssec_name_add_rr(ldns_dnssec_name *name,
-				    ldns_rr *rr)
-{
-	ldns_status result = LDNS_STATUS_OK;
-	ldns_rr_type rr_type;
-	ldns_rr_type typecovered = 0;
-
-	/* special handling for NSEC3 and NSECX covering RRSIGS */
-
-	if (!name || !rr) {
-		return LDNS_STATUS_ERR;
-	}
-
-	rr_type = ldns_rr_get_type(rr);
-
-	if (rr_type == LDNS_RR_TYPE_RRSIG) {
-		typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
-	}
-
-	if (rr_type == LDNS_RR_TYPE_NSEC ||
-	    rr_type == LDNS_RR_TYPE_NSEC3) {
-		/* XX check if is already set (and error?) */
-		name->nsec = rr;
-	} else if (typecovered == LDNS_RR_TYPE_NSEC ||
-			 typecovered == LDNS_RR_TYPE_NSEC3) {
-		if (name->nsec_signatures) {
-			result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr);
-		} else {
-			name->nsec_signatures = ldns_dnssec_rrs_new();
-			name->nsec_signatures->rr = rr;
-		}
-	} else {
-		/* it's a 'normal' RR, add it to the right rrset */
-		if (name->rrsets) {
-			result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
-		} else {
-			name->rrsets = ldns_dnssec_rrsets_new();
-			result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr);
-		}
-	}
-	return result;
-}
-
-ldns_dnssec_rrsets *
-ldns_dnssec_name_find_rrset(ldns_dnssec_name *name,
-					   ldns_rr_type type) {
-	ldns_dnssec_rrsets *result;
-
-	result = name->rrsets;
-	while (result) {
-		if (result->type == type) {
-			return result;
-		} else {
-			result = result->next;
-		}
-	}
-	return NULL;
-}
-
-ldns_dnssec_rrsets *
-ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone,
-					   ldns_rdf *dname,
-					   ldns_rr_type type)
-{
-	ldns_rbnode_t *node;
-
-	if (!zone || !dname || !zone->names) {
-		return NULL;
-	}
-
-	node = ldns_rbtree_search(zone->names, dname);
-	if (node) {
-		return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data,
-									type);
-	} else {
-		return NULL;
-	}
-}
-
-static void
-ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt,
-		ldns_dnssec_name *name, 
-		bool show_soa)
-{
-	if (name) {
-		if(name->rrsets) {
-			ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 
-					name->rrsets, true, show_soa);
-		} else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
-			fprintf(out, ";; Empty nonterminal: ");
-			ldns_rdf_print(out, name->name);
-			fprintf(out, "\n");
-		}
-		if(name->nsec) {
-			ldns_rr_print_fmt(out, fmt, name->nsec);
-		}
-		if (name->nsec_signatures) {
-			ldns_dnssec_rrs_print_fmt(out, fmt, 
-					name->nsec_signatures);
-		}
-	} else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
-		fprintf(out, "; <void>\n");
-	}
-}
-
-
-void
-ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt,
-		ldns_dnssec_name *name)
-{
-	ldns_dnssec_name_print_soa_fmt(out, fmt, name, true);
-}
-
-void
-ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name)
-{
-	ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name);
-}
-
-
-ldns_dnssec_zone *
-ldns_dnssec_zone_new(void)
-{
-	ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone);
-        if(!zone) return NULL;
-	zone->soa = NULL;
-	zone->names = NULL;
-	zone->hashed_names = NULL;
-	zone->_nsec3params = NULL;
-
-	return zone;
-}
-
-static bool
-rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t)
-{
-	return     ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG
-		&& ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t;
-}
-
-/* When the zone is first read into an list and then inserted into an
- * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next)
- * to each other. Because ldns-verify-zone (the only program that uses this
- * function) uses the rbtree mostly for sequentual walking, this results
- * in a speed increase (of 15% on linux) because we have less CPU-cache misses.
- */
-#define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */
-
-static ldns_status
-ldns_dnssec_zone_add_empty_nonterminals_nsec3(
-		ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s);
-
-static void
-ldns_todo_nsec3_ents_node_free(ldns_rbnode_t *node, void *arg) {
-	(void) arg;
-	ldns_rdf_deep_free((ldns_rdf *)node->key);
-	LDNS_FREE(node);
-}
-
-ldns_status
-ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
-	       	uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr)
-{
-	ldns_rr* cur_rr;
-	size_t i;
-
-	ldns_rdf *my_origin = NULL;
-	ldns_rdf *my_prev = NULL;
-
-	ldns_dnssec_zone *newzone = ldns_dnssec_zone_new();
-	/* NSEC3s may occur before the names they refer to. We must remember
-	   them and add them to the name later on, after the name is read.
-	   We track not yet  matching NSEC3s*n the todo_nsec3s list */
-	ldns_rr_list* todo_nsec3s = ldns_rr_list_new();
-	/* when reading NSEC3s, there is a chance that we encounter nsecs
-	   for empty nonterminals, whose nonterminals we cannot derive yet
-	   because the needed information is to be read later.
-
-	   nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will
-	   hold the NSEC3s that still didn't have a matching name in the
-	   zone tree, even after all names were read.  They can only match
-	   after the zone is equiped with all the empty non terminals. */
-	ldns_rbtree_t todo_nsec3_ents;
-	ldns_rbnode_t *new_node;
-	ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new();
-
-	ldns_status status;
-
-#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
-	ldns_zone* zone = NULL;
-#else
-	uint32_t  my_ttl = ttl;
-#endif
-
-	ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v);
-
-#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
-	status = ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr);
-	if (status != LDNS_STATUS_OK)
-		goto error;
-#endif
-	if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) {
-		status = LDNS_STATUS_MEM_ERR;
-		goto error;
-	}
-	if (origin) {
-		if (!(my_origin = ldns_rdf_clone(origin))) {
-			status = LDNS_STATUS_MEM_ERR;
-			goto error;
-		}
-		if (!(my_prev   = ldns_rdf_clone(origin))) {
-			status = LDNS_STATUS_MEM_ERR;
-			goto error;
-		}
-	}
-
-#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
-	if (ldns_zone_soa(zone)) {
-		status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone));
-		if (status != LDNS_STATUS_OK)
-			goto error;
-	}
-	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
-		cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i);
-		status = LDNS_STATUS_OK;
-#else
-	while (!feof(fp)) {
-		status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin,
-				&my_prev, line_nr);
-
-#endif
-		switch (status) {
-		case LDNS_STATUS_OK:
-
-			status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
-			if (status ==
-				LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) {
-
-				if (rr_is_rrsig_covering(cur_rr,
-							LDNS_RR_TYPE_NSEC3)){
-					ldns_rr_list_push_rr(todo_nsec3_rrsigs,
-							cur_rr);
-				} else {
-					ldns_rr_list_push_rr(todo_nsec3s,
-						       	cur_rr);
-				}
-				status = LDNS_STATUS_OK;
-
-			} else if (status != LDNS_STATUS_OK)
-				goto error;
-
-			break;
-
-
-		case LDNS_STATUS_SYNTAX_EMPTY:	/* empty line was seen */
-		case LDNS_STATUS_SYNTAX_TTL:	/* the ttl was set*/
-		case LDNS_STATUS_SYNTAX_ORIGIN:	/* the origin was set*/
-			status = LDNS_STATUS_OK;
-			break;
-
-		case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */
-			status =  LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
-			break;
-
-		default:
-			goto error;
-		}
-	}
-
-	for (i = 0; status == LDNS_STATUS_OK &&
-			i < ldns_rr_list_rr_count(todo_nsec3s); i++) {
-		cur_rr = ldns_rr_list_rr(todo_nsec3s, i);
-		status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
-		if (status == LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) {
-			if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) {
-				status = LDNS_STATUS_MEM_ERR;
-				break;
-			}
-			new_node->key  = ldns_dname_label(ldns_rr_owner(cur_rr), 0);
-			new_node->data = cur_rr;
-			if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) {
-				LDNS_FREE(new_node);
-				status = LDNS_STATUS_MEM_ERR;
-				break;
-			}
-			status = LDNS_STATUS_OK;
-		}
-	}
-	if (todo_nsec3_ents.count > 0)
-		(void) ldns_dnssec_zone_add_empty_nonterminals_nsec3(
-				newzone, &todo_nsec3_ents);
-	for (i = 0; status == LDNS_STATUS_OK &&
-			i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) {
-		cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i);
-		status = ldns_dnssec_zone_add_rr(newzone, cur_rr);
-	}
-	if (z) {
-		*z = newzone;
-		newzone = NULL;
-	} else {
-		ldns_dnssec_zone_free(newzone);
-	}
-
-error:
-#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP
-	if (zone) {
-		ldns_zone_free(zone);
-	}
-#endif
-	ldns_rr_list_free(todo_nsec3_rrsigs);
-	ldns_traverse_postorder(&todo_nsec3_ents,
-			ldns_todo_nsec3_ents_node_free, NULL);
-	ldns_rr_list_free(todo_nsec3s);
-
-	if (my_origin) {
-		ldns_rdf_deep_free(my_origin);
-	}
-	if (my_prev) {
-		ldns_rdf_deep_free(my_prev);
-	}
-	if (newzone) {
-		ldns_dnssec_zone_free(newzone);
-	}
-	return status;
-}
-
-ldns_status
-ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin,
-		uint32_t ttl, ldns_rr_class ATTR_UNUSED(c))
-{
-	return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
-}
-
-static void
-ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) {
-	(void) arg;
-	ldns_dnssec_name_free((ldns_dnssec_name *)node->data);
-	LDNS_FREE(node);
-}
-
-static void
-ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) {
-	(void) arg;
-	ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data);
-	LDNS_FREE(node);
-}
-
-void
-ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
-{
-	if (zone) {
-		if (zone->names) {
-			/* destroy all name structures within the tree */
-			ldns_traverse_postorder(zone->names,
-						    ldns_dnssec_name_node_free,
-						    NULL);
-			LDNS_FREE(zone->names);
-		}
-		LDNS_FREE(zone);
-	}
-}
-
-void
-ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
-{
-	if (zone) {
-		if (zone->names) {
-			/* destroy all name structures within the tree */
-			ldns_traverse_postorder(zone->names,
-						    ldns_dnssec_name_node_deep_free,
-						    NULL);
-			LDNS_FREE(zone->names);
-		}
-		LDNS_FREE(zone);
-	}
-}
-
-/* use for dname comparison in tree */
-int
-ldns_dname_compare_v(const void *a, const void *b) {
-	return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b);
-}
-
-static void
-ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
-		ldns_dnssec_name* name, ldns_rr* nsec3rr);
-
-static void
-ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
-	(void) arg;
-	LDNS_FREE(node);
-}
-
-static void
-ldns_dnssec_zone_hashed_names_from_nsec3(
-		ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
-{
-	ldns_rbnode_t* current_node;
-	ldns_dnssec_name* current_name;
-
-	assert(zone != NULL);
-	assert(nsec3rr != NULL);
-
-	if (zone->hashed_names) {
-		ldns_traverse_postorder(zone->hashed_names,
-				ldns_hashed_names_node_free, NULL);
-		LDNS_FREE(zone->hashed_names);
-	}
-	zone->_nsec3params = nsec3rr;
-
-	/* So this is a NSEC3 zone.
-	* Calculate hashes for all names already in the zone
-	*/
-	zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
-	if (zone->hashed_names == NULL) {
-		return;
-	}
-	for ( current_node  = ldns_rbtree_first(zone->names)
-	    ; current_node != LDNS_RBTREE_NULL
-	    ; current_node  = ldns_rbtree_next(current_node)
-	    ) {
-		current_name = (ldns_dnssec_name *) current_node->data;
-		ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);
-
-	}
-}
-
-static void
-ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone,
-		ldns_dnssec_name* name, ldns_rr* nsec3rr)
-{
-	ldns_rbnode_t* new_node;
-
-	assert(name != NULL);
-	if (! zone->_nsec3params) {
-		if (! nsec3rr) {
-			return;
-		}
-		ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr);
-
-	} else if (! nsec3rr) {
-		nsec3rr = zone->_nsec3params;
-	}
-	name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name);
-
-	/* Also store in zone->hashed_names */
-	if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) {
-
-		new_node->key  = name->hashed_name;
-		new_node->data = name;
-
-		if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) {
-
-				LDNS_FREE(new_node);
-		}
-	}
-}
-
-
-static ldns_rbnode_t *
-ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
-	ldns_rdf *hashed_name;
-
-	hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
-	if (hashed_name == NULL) {
-		return NULL;
-	}
-	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
-
-		ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
-	}
-	if (zone->hashed_names == NULL) {
-		ldns_rdf_deep_free(hashed_name);
-		return NULL;
-	}
-	return  ldns_rbtree_search(zone->hashed_names, hashed_name);
-}
-
-ldns_status
-ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
-{
-	ldns_status result = LDNS_STATUS_OK;
-	ldns_dnssec_name *cur_name;
-	ldns_rbnode_t *cur_node;
-	ldns_rr_type type_covered = 0;
-
-	if (!zone || !rr) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (!zone->names) {
-		zone->names = ldns_rbtree_create(ldns_dname_compare_v);
-                if(!zone->names) return LDNS_STATUS_MEM_ERR;
-	}
-
-	/* we need the original of the hashed name if this is
-	   an NSEC3, or an RRSIG that covers an NSEC3 */
-	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) {
-		type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
-	}
-	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 ||
-	    type_covered == LDNS_RR_TYPE_NSEC3) {
-		cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr);
-		if (!cur_node) {
-			return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND;
-		}
-	} else {
-		cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr));
-	}
-	if (!cur_node) {
-		/* add */
-		cur_name = ldns_dnssec_name_new_frm_rr(rr);
-                if(!cur_name) return LDNS_STATUS_MEM_ERR;
-		cur_node = LDNS_MALLOC(ldns_rbnode_t);
-                if(!cur_node) {
-                        ldns_dnssec_name_free(cur_name);
-                        return LDNS_STATUS_MEM_ERR;
-                }
-		cur_node->key = ldns_rr_owner(rr);
-		cur_node->data = cur_name;
-		(void)ldns_rbtree_insert(zone->names, cur_node);
-		ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL);
-	} else {
-		cur_name = (ldns_dnssec_name *) cur_node->data;
-		result = ldns_dnssec_name_add_rr(cur_name, rr);
-	}
-	if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
-		zone->soa = cur_name;
-	}
-	return result;
-}
-
-void
-ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
-		ldns_rbtree_t *tree, 
-		bool print_soa)
-{
-	ldns_rbnode_t *node;
-	ldns_dnssec_name *name;
-
-	node = ldns_rbtree_first(tree);
-	while (node != LDNS_RBTREE_NULL) {
-		name = (ldns_dnssec_name *) node->data;
-		ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
-		if ((fmt->flags & LDNS_COMMENT_LAYOUT))
-			fprintf(out, ";\n");
-		node = ldns_rbtree_next(node);
-	}
-}
-
-void
-ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa)
-{
-	ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default,
-		       tree, print_soa);
-}
-
-void
-ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt,
-	       ldns_dnssec_zone *zone)
-{
-	if (zone) {
-		if (zone->soa) {
-			if ((fmt->flags & LDNS_COMMENT_LAYOUT)) {
-				fprintf(out, ";; Zone: ");
-				ldns_rdf_print(out, ldns_dnssec_name_name(
-							zone->soa));
-				fprintf(out, "\n;\n");
-			}
-			ldns_dnssec_rrsets_print_fmt(out, fmt,
-					ldns_dnssec_name_find_rrset(
-						zone->soa, 
-						LDNS_RR_TYPE_SOA), 
-					false);
-			if ((fmt->flags & LDNS_COMMENT_LAYOUT))
-				fprintf(out, ";\n");
-		}
-
-		if (zone->names) {
-			ldns_dnssec_zone_names_print_fmt(out, fmt, 
-					zone->names, false);
-		}
-	}
-}
-
-void
-ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
-{
-	ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone);
-}
-
-static ldns_status
-ldns_dnssec_zone_add_empty_nonterminals_nsec3(
-		ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s)
-{
-	ldns_dnssec_name *new_name;
-	ldns_rdf *cur_name;
-	ldns_rdf *next_name;
-	ldns_rbnode_t *cur_node, *next_node, *new_node;
-
-	/* for the detection */
-	uint16_t i, cur_label_count, next_label_count;
-	uint16_t soa_label_count = 0;
-	ldns_rdf *l1, *l2;
-	int lpos;
-
-	if (!zone) {
-		return LDNS_STATUS_ERR;
-	}
-	if (zone->soa && zone->soa->name) {
-		soa_label_count = ldns_dname_label_count(zone->soa->name);
-	}
-	
-	cur_node = ldns_rbtree_first(zone->names);
-	while (cur_node != LDNS_RBTREE_NULL) {
-		next_node = ldns_rbtree_next(cur_node);
-		
-		/* skip glue */
-		while (next_node != LDNS_RBTREE_NULL && 
-		       next_node->data &&
-		       ((ldns_dnssec_name *)next_node->data)->is_glue
-		) {
-			next_node = ldns_rbtree_next(next_node);
-		}
-
-		if (next_node == LDNS_RBTREE_NULL) {
-			next_node = ldns_rbtree_first(zone->names);
-		}
-		if (! cur_node->data || ! next_node->data) {
-			return LDNS_STATUS_ERR;
-		}
-		cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
-		next_name = ((ldns_dnssec_name *)next_node->data)->name;
-		cur_label_count = ldns_dname_label_count(cur_name);
-		next_label_count = ldns_dname_label_count(next_name);
-
-		/* Since the names are in canonical order, we can
-		 * recognize empty non-terminals by their labels;
-		 * every label after the first one on the next owner
-		 * name is a non-terminal if it either does not exist
-		 * in the current name or is different from the same
-		 * label in the current name (counting from the end)
-		 */
-		for (i = 1; i < next_label_count - soa_label_count; i++) {
-			lpos = (int)cur_label_count - (int)next_label_count + (int)i;
-			if (lpos >= 0) {
-				l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
-			} else {
-				l1 = NULL;
-			}
-			l2 = ldns_dname_clone_from(next_name, i);
-
-			if (!l1 || ldns_dname_compare(l1, l2) != 0) {
-				/* We have an empty nonterminal, add it to the
-				 * tree
-				 */
-				ldns_rbnode_t *node = NULL;
-				ldns_rdf *ent_name;
-
-				if (!(ent_name = ldns_dname_clone_from(
-						next_name, i)))
-					return LDNS_STATUS_MEM_ERR;
-
-				if (nsec3s && zone->_nsec3params) {
-					ldns_rdf *ent_hashed_name;
-
-					if (!(ent_hashed_name =
-					    ldns_nsec3_hash_name_frm_nsec3(
-							zone->_nsec3params,
-							ent_name)))
-						return LDNS_STATUS_MEM_ERR;
-					node = ldns_rbtree_search(nsec3s, 
-							ent_hashed_name);
-					if (!node) {
-						ldns_rdf_deep_free(l1);
-						ldns_rdf_deep_free(l2);
-						continue;
-					}
-				}
-				new_name = ldns_dnssec_name_new();
-				if (!new_name) {
-					return LDNS_STATUS_MEM_ERR;
-				}
-				new_name->name = ent_name;
-				if (!new_name->name) {
-					ldns_dnssec_name_free(new_name);
-					return LDNS_STATUS_MEM_ERR;
-				}
-				new_name->name_alloced = true;
-				new_node = LDNS_MALLOC(ldns_rbnode_t);
-				if (!new_node) {
-					ldns_dnssec_name_free(new_name);
-					return LDNS_STATUS_MEM_ERR;
-				}
-				new_node->key = new_name->name;
-				new_node->data = new_name;
-				(void)ldns_rbtree_insert(zone->names, new_node);
-				ldns_dnssec_name_make_hashed_name(
-						zone, new_name, NULL);
-				if (node)
-					(void) ldns_dnssec_zone_add_rr(zone,
-							(ldns_rr *)node->data);
-			}
-			ldns_rdf_deep_free(l1);
-			ldns_rdf_deep_free(l2);
-		}
-		
-		/* we might have inserted a new node after
-		 * the current one so we can't just use next()
-		 */
-		if (next_node != ldns_rbtree_first(zone->names)) {
-			cur_node = next_node;
-		} else {
-			cur_node = LDNS_RBTREE_NULL;
-		}
-	}
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
-{
-	return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL);
-}
-
-bool
-ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone)
-{
-	ldns_rr* nsec3;
-	ldns_rbnode_t* node;
-
-	if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) {
-		node = ldns_rbtree_first(zone->names);
-		while (node != LDNS_RBTREE_NULL) {
-			nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
-			if (nsec3 &&ldns_rr_get_type(nsec3) 
-					== LDNS_RR_TYPE_NSEC3 &&
-					ldns_nsec3_optout(nsec3)) {
-				return true;
-			}
-			node = ldns_rbtree_next(node);
-		}
-	}
-	return false;
-}
diff --git a/src/ldns/duration.c b/src/ldns/duration.c
deleted file mode 100644
index 6d0a388..0000000
--- a/src/ldns/duration.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * $Id: duration.c 4518 2011-02-24 15:39:09Z matthijs $
- *
- * Copyright (c) 2009 NLNet Labs. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- *
- * This file is copied from the OpenDNSSEC source repository
- * and only slightly adapted to make it fit.
- */
-
-/**
- *
- * Durations.
- */
-
-#include <ldns/config.h>
-#include <ldns/duration.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-
-/**
- * Create a new 'instant' duration.
- *
- */
-ldns_duration_type*
-ldns_duration_create(void)
-{
-    ldns_duration_type* duration;
-
-    duration = malloc(sizeof(ldns_duration_type));
-    if (!duration) {
-        return NULL;
-    }
-    duration->years = 0;
-    duration->months = 0;
-    duration->weeks = 0;
-    duration->days = 0;
-    duration->hours = 0;
-    duration->minutes = 0;
-    duration->seconds = 0;
-    return duration;
-}
-
-
-/**
- * Compare durations.
- *
- */
-int
-ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2)
-{
-    if (!d1 && !d2) {
-        return 0;
-    }
-    if (!d1 || !d2) {
-        return d1?-1:1;
-    }
-
-    if (d1->years != d2->years) {
-        return (int) (d1->years - d2->years);
-    }
-    if (d1->months != d2->months) {
-        return (int) (d1->months - d2->months);
-    }
-    if (d1->weeks != d2->weeks) {
-        return (int) (d1->weeks - d2->weeks);
-    }
-    if (d1->days != d2->days) {
-        return (int) (d1->days - d2->days);
-    }
-    if (d1->hours != d2->hours) {
-        return (int) (d1->hours - d2->hours);
-    }
-    if (d1->minutes != d2->minutes) {
-        return (int) (d1->minutes - d2->minutes);
-    }
-    if (d1->seconds != d2->seconds) {
-        return (int) (d1->seconds - d2->seconds);
-    }
-
-    return 0;
-}
-
-
-/**
- * Create a duration from string.
- *
- */
-ldns_duration_type*
-ldns_duration_create_from_string(const char* str)
-{
-    ldns_duration_type* duration = ldns_duration_create();
-    char* P, *X, *T, *W;
-    int not_weeks = 0;
-
-    if (!duration) {
-        return NULL;
-    }
-    if (!str) {
-        return duration;
-    }
-
-    P = strchr(str, 'P');
-    if (!P) {
-	ldns_duration_cleanup(duration);
-        return NULL;
-    }
-
-    T = strchr(str, 'T');
-    X = strchr(str, 'Y');
-    if (X) {
-        duration->years = (time_t) atoi(str+1);
-        str = X;
-        not_weeks = 1;
-    }
-    X = strchr(str, 'M');
-    if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) {
-        duration->months = (time_t) atoi(str+1);
-        str = X;
-        not_weeks = 1;
-    }
-    X = strchr(str, 'D');
-    if (X) {
-        duration->days = (time_t) atoi(str+1);
-        str = X;
-        not_weeks = 1;
-    }
-    if (T) {
-        str = T;
-        not_weeks = 1;
-    }
-    X = strchr(str, 'H');
-    if (X && T) {
-        duration->hours = (time_t) atoi(str+1);
-        str = X;
-        not_weeks = 1;
-    }
-    X = strrchr(str, 'M');
-    if (X && T && (size_t) (X-P) > (size_t) (T-P)) {
-        duration->minutes = (time_t) atoi(str+1);
-        str = X;
-        not_weeks = 1;
-    }
-    X = strchr(str, 'S');
-    if (X && T) {
-        duration->seconds = (time_t) atoi(str+1);
-        str = X;
-        not_weeks = 1;
-    }
-
-    W = strchr(str, 'W');
-    if (W) {
-        if (not_weeks) {
-            ldns_duration_cleanup(duration);
-            return NULL;
-        } else {
-            duration->weeks = (time_t) atoi(str+1);
-            str = W;
-        }
-    }
-    return duration;
-}
-
-
-/**
- * Get the number of digits in a number.
- *
- */
-static size_t
-digits_in_number(time_t duration)
-{
-    uint32_t period = (uint32_t) duration;
-    size_t count = 0;
-
-    while (period > 0) {
-        count++;
-        period /= 10;
-    }
-    return count;
-}
-
-
-/**
- * Convert a duration to a string.
- *
- */
-char*
-ldns_duration2string(ldns_duration_type* duration)
-{
-    char* str = NULL, *num = NULL;
-    size_t count = 2;
-    int T = 0;
-
-    if (!duration) {
-        return NULL;
-    }
-
-    if (duration->years > 0) {
-        count = count + 1 + digits_in_number(duration->years);
-    }
-    if (duration->months > 0) {
-        count = count + 1 + digits_in_number(duration->months);
-    }
-    if (duration->weeks > 0) {
-        count = count + 1 + digits_in_number(duration->weeks);
-    }
-    if (duration->days > 0) {
-        count = count + 1 + digits_in_number(duration->days);
-    }
-    if (duration->hours > 0) {
-        count = count + 1 + digits_in_number(duration->hours);
-        T = 1;
-    }
-    if (duration->minutes > 0) {
-        count = count + 1 + digits_in_number(duration->minutes);
-        T = 1;
-    }
-    if (duration->seconds > 0) {
-        count = count + 1 + digits_in_number(duration->seconds);
-        T = 1;
-    }
-    if (T) {
-        count++;
-    }
-
-    str = (char*) calloc(count, sizeof(char));
-    str[0] = 'P';
-    str[1] = '\0';
-
-    if (duration->years > 0) {
-        count = digits_in_number(duration->years);
-        num = (char*) calloc(count+2, sizeof(char));
-        snprintf(num, count+2, "%uY", (unsigned int) duration->years);
-        str = strncat(str, num, count+2);
-        free((void*) num);
-    }
-    if (duration->months > 0) {
-        count = digits_in_number(duration->months);
-        num = (char*) calloc(count+2, sizeof(char));
-        snprintf(num, count+2, "%uM", (unsigned int) duration->months);
-        str = strncat(str, num, count+2);
-        free((void*) num);
-    }
-    if (duration->weeks > 0) {
-        count = digits_in_number(duration->weeks);
-        num = (char*) calloc(count+2, sizeof(char));
-        snprintf(num, count+2, "%uW", (unsigned int) duration->weeks);
-        str = strncat(str, num, count+2);
-        free((void*) num);
-    }
-    if (duration->days > 0) {
-        count = digits_in_number(duration->days);
-        num = (char*) calloc(count+2, sizeof(char));
-        snprintf(num, count+2, "%uD", (unsigned int) duration->days);
-        str = strncat(str, num, count+2);
-        free((void*) num);
-    }
-    if (T) {
-        str = strncat(str, "T", 1);
-    }
-    if (duration->hours > 0) {
-        count = digits_in_number(duration->hours);
-        num = (char*) calloc(count+2, sizeof(char));
-        snprintf(num, count+2, "%uH", (unsigned int) duration->hours);
-        str = strncat(str, num, count+2);
-        free((void*) num);
-    }
-    if (duration->minutes > 0) {
-        count = digits_in_number(duration->minutes);
-        num = (char*) calloc(count+2, sizeof(char));
-        snprintf(num, count+2, "%uM", (unsigned int) duration->minutes);
-        str = strncat(str, num, count+2);
-        free((void*) num);
-    }
-    if (duration->seconds > 0) {
-        count = digits_in_number(duration->seconds);
-        num = (char*) calloc(count+2, sizeof(char));
-        snprintf(num, count+2, "%uS", (unsigned int) duration->seconds);
-        str = strncat(str, num, count+2);
-        free((void*) num);
-    }
-    return str;
-}
-
-
-/**
- * Convert a duration to a time.
- *
- */
-time_t
-ldns_duration2time(ldns_duration_type* duration)
-{
-    time_t period = 0;
-
-    if (duration) {
-        period += (duration->seconds);
-        period += (duration->minutes)*60;
-        period += (duration->hours)*3600;
-        period += (duration->days)*86400;
-        period += (duration->weeks)*86400*7;
-        period += (duration->months)*86400*31;
-        period += (duration->years)*86400*365;
-
-        /* [TODO] calculate correct number of days in this month/year */
-	/*
-        if (duration->months || duration->years) {
-        }
-	*/
-    }
-    return period;
-}
-
-
-/**
- * Clean up duration.
- *
- */
-void
-ldns_duration_cleanup(ldns_duration_type* duration)
-{
-    if (!duration) {
-        return;
-    }
-    free(duration);
-    return;
-}
diff --git a/src/ldns/error.c b/src/ldns/error.c
deleted file mode 100644
index 82ea61a..0000000
--- a/src/ldns/error.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * a error2str function to make sense of all the
- * error codes we have laying ardoun
- *
- * a Net::DNS like library for C
- * LibDNS Team @ NLnet Labs
- * (c) NLnet Labs, 2005-2006
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-ldns_lookup_table ldns_error_str[] = {
-	{ LDNS_STATUS_OK, "All OK" },
-	{ LDNS_STATUS_EMPTY_LABEL, "Empty label" },
-        { LDNS_STATUS_LABEL_OVERFLOW, "Label length overflow" },
-        { LDNS_STATUS_DOMAINNAME_OVERFLOW, "Domainname length overflow" },
-        { LDNS_STATUS_DOMAINNAME_UNDERFLOW, "Domainname length underflow (zero length)" },
-        { LDNS_STATUS_DDD_OVERFLOW, "\\DDD sequence overflow (>255)" },
-        { LDNS_STATUS_PACKET_OVERFLOW, "Packet size overflow" },
-        { LDNS_STATUS_INVALID_POINTER, "Invalid compression pointer" },
-        { LDNS_STATUS_MEM_ERR, "General memory error" },
-        { LDNS_STATUS_INTERNAL_ERR, "Internal error, this should not happen" },
-        { LDNS_STATUS_SSL_ERR, "Error in SSL library" },
-        { LDNS_STATUS_ERR, "General LDNS error" },
-        { LDNS_STATUS_INVALID_INT, "Conversion error, integer expected" },
-        { LDNS_STATUS_INVALID_IP4, "Conversion error, ip4 addr expected" },
-        { LDNS_STATUS_INVALID_IP6, "Conversion error, ip6 addr expected" },
-        { LDNS_STATUS_INVALID_STR, "Conversion error, string expected" },
-	{ LDNS_STATUS_INVALID_B32_EXT, "Conversion error, b32 ext encoding expected" },
-        { LDNS_STATUS_INVALID_B64, "Conversion error, b64 encoding expected" },
-        { LDNS_STATUS_INVALID_HEX, "Conversion error, hex encoding expected" },
-        { LDNS_STATUS_INVALID_TIME, "Conversion error, time encoding expected" },
-        { LDNS_STATUS_NETWORK_ERR, "Could not send or receive, because of network error" },
-        { LDNS_STATUS_ADDRESS_ERR, "Could not start AXFR, because of address error" },
-        { LDNS_STATUS_FILE_ERR, "Could not open the files" },
-        { LDNS_STATUS_UNKNOWN_INET, "Uknown address family" },
-        { LDNS_STATUS_NOT_IMPL, "This function is not implemented (yet), please notify the developers - or not..." },
-	{ LDNS_STATUS_NULL, "Supplied value pointer null" },
-        { LDNS_STATUS_CRYPTO_UNKNOWN_ALGO, "Unknown cryptographic algorithm" },
-        { LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL, "Cryptographic algorithm not implemented" },
-        { LDNS_STATUS_CRYPTO_NO_RRSIG, "No DNSSEC signature(s)" },
-        { LDNS_STATUS_CRYPTO_NO_DNSKEY, "No DNSSEC public key(s)" },
-        { LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR, "The signature does not cover this RRset" },
-        { LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY, "No signatures found for trusted DNSSEC public key(s)" },
-        { LDNS_STATUS_CRYPTO_NO_DS, "No DS record(s)" },
-        { LDNS_STATUS_CRYPTO_NO_TRUSTED_DS, "Could not validate DS record(s)" },
-        { LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY, "No keys with the keytag and algorithm from the RRSIG found" },
-        { LDNS_STATUS_CRYPTO_VALIDATED, "Valid DNSSEC signature" },
-        { LDNS_STATUS_CRYPTO_BOGUS, "Bogus DNSSEC signature" },
-        { LDNS_STATUS_CRYPTO_SIG_EXPIRED, "DNSSEC signature has expired" },
-        { LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED, "DNSSEC signature not incepted yet" },
-	{ LDNS_STATUS_CRYPTO_TSIG_BOGUS, "Bogus TSIG signature" },
-	{ LDNS_STATUS_CRYPTO_TSIG_ERR, "Could not create TSIG signature" },
-        { LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION, "DNSSEC signature has expiration date earlier than inception date" },
-	{ LDNS_STATUS_ENGINE_KEY_NOT_LOADED, "Unable to load private key from engine" },
-        { LDNS_STATUS_NSEC3_ERR, "Error in NSEC3 denial of existence proof" },
-	{ LDNS_STATUS_RES_NO_NS, "No (valid) nameservers defined in the resolver" },
-	{ LDNS_STATUS_RES_QUERY, "No correct query given to resolver" },
-	{ LDNS_STATUS_WIRE_INCOMPLETE_HEADER, "header section incomplete" },
-	{ LDNS_STATUS_WIRE_INCOMPLETE_QUESTION, "question section incomplete" },
-	{ LDNS_STATUS_WIRE_INCOMPLETE_ANSWER, "answer section incomplete" },
-	{ LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY, "authority section incomplete" },
-	{ LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL, "additional section incomplete" },
-	{ LDNS_STATUS_NO_DATA, "No data" },
-	{ LDNS_STATUS_EXISTS_ERR, "Element already exists" },
-	{ LDNS_STATUS_CERT_BAD_ALGORITHM, "Bad algorithm type for CERT record" },
-	{ LDNS_STATUS_SYNTAX_TYPE_ERR, "Syntax error, could not parse the RR's type" },
-	{ LDNS_STATUS_SYNTAX_CLASS_ERR, "Syntax error, could not parse the RR's class" },
-	{ LDNS_STATUS_SYNTAX_TTL_ERR, "Syntax error, could not parse the RR's TTL" },
-	{ LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL, "Syntax error, $INCLUDE not implemented" },
-	{ LDNS_STATUS_SYNTAX_RDATA_ERR, "Syntax error, could not parse the RR's rdata" },
-	{ LDNS_STATUS_SYNTAX_DNAME_ERR, "Syntax error, could not parse the RR's dname(s)" },
-	{ LDNS_STATUS_SYNTAX_VERSION_ERR, "Syntax error, version mismatch" },
-	{ LDNS_STATUS_SYNTAX_ALG_ERR, "Syntax error, algorithm unknown or non parseable" },
-	{ LDNS_STATUS_SYNTAX_KEYWORD_ERR, "Syntax error, unknown keyword in input" },
-	{ LDNS_STATUS_SYNTAX_ERR, "Syntax error, could not parse the RR" },
-	{ LDNS_STATUS_SYNTAX_EMPTY, "Empty line was returned" },
-	{ LDNS_STATUS_SYNTAX_TTL, "$TTL directive was seen in the zone" },
-	{ LDNS_STATUS_SYNTAX_ORIGIN, "$ORIGIN directive was seen in the zone" },
-	{ LDNS_STATUS_SYNTAX_INCLUDE, "$INCLUDE directive was seen in the zone" },
-	{ LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW, "Iterations count for NSEC3 record higher than maximum" },
-	{ LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR, "Syntax error, value expected" },
-	{ LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer value too large" },
-	{ LDNS_STATUS_SYNTAX_BAD_ESCAPE, "Syntax error, bad escape sequence" },
-	{ LDNS_STATUS_SOCKET_ERROR, "Error creating socket" },
-	{ LDNS_STATUS_DNSSEC_EXISTENCE_DENIED, "Existence denied by NSEC" },
-	{ LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED, "RR not covered by the given NSEC RRs" },
-	{ LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED, "wildcard not covered by the given NSEC RRs" },
-	{ LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND, "original of NSEC3 hashed name could not be found" },
-	{ LDNS_STATUS_MISSING_RDATA_FIELDS_RRSIG, "The RRSIG has to few rdata fields" },
-	{ LDNS_STATUS_MISSING_RDATA_FIELDS_KEY, "The DNSKEY has to few rdata fields" },
-	{ LDNS_STATUS_CRYPTO_SIG_EXPIRED_WITHIN_MARGIN, 
-		"DNSSEC signature will expire too soon" },
-	{ LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED_WITHIN_MARGIN,
-		"DNSSEC signature not incepted long enough" },
-	{ LDNS_STATUS_DANE_UNKNOWN_CERTIFICATE_USAGE,
-		"Unknown TLSA Certificate Usage" },
-	{ LDNS_STATUS_DANE_UNKNOWN_SELECTOR, "Unknown TLSA Selector" },
-	{ LDNS_STATUS_DANE_UNKNOWN_MATCHING_TYPE,
-		"Unknown TLSA Matching Type" },
-	{ LDNS_STATUS_DANE_UNKNOWN_PROTOCOL,
-		"Unknown protocol. Only IPv4 and IPv6 are understood" },
-	{ LDNS_STATUS_DANE_UNKNOWN_TRANSPORT,
-		"Unknown transport. Should be one of {tcp, udp, sctp}" },
-	{ LDNS_STATUS_DANE_MISSING_EXTRA_CERTS,  /* Trust anchor assertion */
-		"More than one certificate should be provided" },
-	{ LDNS_STATUS_DANE_EXTRA_CERTS_NOT_USED, /* Trust anchor assertion */
-		"Non of the extra certificates is used to sign the first" },
-	{ LDNS_STATUS_DANE_OFFSET_OUT_OF_RANGE,   /* Trust anchor assertion */
-		"The offset was out of range" },
-	{ LDNS_STATUS_DANE_INSECURE,             /* Unused by library */
-		"The queried resource records were insecure" },
-	{ LDNS_STATUS_DANE_BOGUS,             /* Unused by library */
-		"The queried resource records were bogus" },
-	{ LDNS_STATUS_DANE_TLSA_DID_NOT_MATCH,
-		"The TLSA record(s) "
-		"did not match with the server certificate (chain)" },
-	{ LDNS_STATUS_DANE_NON_CA_CERTIFICATE,
-		"The certificate was not a CA certificate" },
-	{ LDNS_STATUS_DANE_PKIX_DID_NOT_VALIDATE,
-		"Could not PKIX validate" },
-	{ LDNS_STATUS_DANE_PKIX_NO_SELF_SIGNED_TRUST_ANCHOR,
-		"The validation path "
-		"did not end in a self-signed certificate" },
-        { LDNS_STATUS_INVALID_ILNP64, 
-		"Conversion error, 4 colon separated hex numbers expected" },
-        { LDNS_STATUS_INVALID_EUI48, 
-		"Conversion error, 6 two character hex numbers "
-		"separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx" },
-        { LDNS_STATUS_INVALID_EUI64, 
-		"Conversion error, 8 two character hex numbers "
-		"separated by dashes expected (i.e. xx-xx-xx-xx-xx-xx-xx-xx" },
-	{ LDNS_STATUS_WIRE_RDATA_ERR, "invalid rdata in wire format" },
-        { LDNS_STATUS_INVALID_TAG, 
-		"Conversion error, a non-zero sequence of US-ASCII letters "
-		"and numbers in lower case expected" },
-        { LDNS_STATUS_TYPE_NOT_IN_BITMAP, 
-		"The RR type bitmap rdata field did not have "
-		"a bit reserved for the specific RR type" },
-        { LDNS_STATUS_INVALID_RDF_TYPE, 
-		"The rdata field was not of the expected type" },
-        { LDNS_STATUS_RDATA_OVERFLOW, "Rdata size overflow" },
-	{ 0, NULL }
-};
-
-const char *
-ldns_get_errorstr_by_id(ldns_status err)
-{
-        ldns_lookup_table *lt;
-
-        lt = ldns_lookup_by_id(ldns_error_str, err);
-
-        if (lt) {
-                return lt->name;
-        }
-        return NULL;
-}
diff --git a/src/ldns/higher.c b/src/ldns/higher.c
deleted file mode 100644
index 8ce86a4..0000000
--- a/src/ldns/higher.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * higher.c
- *
- * Specify some higher level functions that would
- * be usefull to would be developers
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#ifdef HAVE_SSL
-#include <openssl/ssl.h>
-#include <openssl/sha.h>
-#endif /* HAVE_SSL */
-
-ldns_rr_list *
-ldns_get_rr_list_addr_by_name(ldns_resolver *res, ldns_rdf *name, ldns_rr_class c, 
-		uint16_t flags)
-{
-	ldns_pkt *pkt;
-	ldns_rr_list *aaaa;
-	ldns_rr_list *a;
-	ldns_rr_list *result = NULL;
-	ldns_rr_list *hostsfilenames;
-	size_t i;
-	uint8_t ip6;
-
-	a = NULL; 
-	aaaa = NULL; 
-	result = NULL;
-
-	if (!res) {
-		return NULL;
-	}
-	if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
-		return NULL;
-	}
-
-	ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
-					 what was there */
-
-	ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
-	
-	hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
-	for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
-		if (ldns_rdf_compare(name, 
-					ldns_rr_owner(ldns_rr_list_rr(hostsfilenames, 
-							i))) == 0) {
-			if (!result) {
-				result = ldns_rr_list_new();
-			}
-			ldns_rr_list_push_rr(result, 
-					ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
-		}
-	}
-	ldns_rr_list_deep_free(hostsfilenames);
-
-	if (result) {
-		return result;
-	}
-
-	/* add the RD flags, because we want an answer */
-	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
-	if (pkt) {
-		/* extract the data we need */
-		aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA, 
-			LDNS_SECTION_ANSWER);
-		ldns_pkt_free(pkt);
-	} 
-
-	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
-	if (pkt) {
-		/* extract the data we need */
-		a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
-		ldns_pkt_free(pkt);
-	} 
-	ldns_resolver_set_ip6(res, ip6);
-
-	if (aaaa && a) {
-		result = ldns_rr_list_cat_clone(aaaa, a);
-		ldns_rr_list_deep_free(aaaa);
-		ldns_rr_list_deep_free(a);
-		return result;
-	}
-	
-	if (aaaa) {
-		result = ldns_rr_list_clone(aaaa);
-	}
-	
-	if (a) {
-		result = ldns_rr_list_clone(a);
-	}
-
-	ldns_rr_list_deep_free(aaaa);
-	ldns_rr_list_deep_free(a);
-	return result;
-}
-
-ldns_rr_list *
-ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class c, 
-		uint16_t flags)
-{
-	ldns_pkt *pkt;
-	ldns_rr_list *names;
-	ldns_rdf *name;
-
-	names = NULL;
-
-	if (!res || !addr) {
-		return NULL;
-	}
-
-	if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
-			ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
-		return NULL;
-	}
-
-	name = ldns_rdf_address_reverse(addr);
-	
-	/* add the RD flags, because we want an answer */
-	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
-	ldns_rdf_deep_free(name);
-	if (pkt) {
-		/* extract the data we need */
-		names = ldns_pkt_rr_list_by_type(pkt, 
-				LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
-		ldns_pkt_free(pkt);
-	}
-	return names;
-}
-
-/* read a line, put it in a buffer, parse the buffer */
-ldns_rr_list *
-ldns_get_rr_list_hosts_frm_fp(FILE *fp)
-{
-	return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
-}
-
-ldns_rr_list *
-ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
-{
-	ssize_t i, j;
-	size_t cnt;
-	char *line;
-	char *word;
-	char *addr;
-	char *rr_str;
-	ldns_buffer *linebuf;
-	ldns_rr *rr;
-	ldns_rr_list *list;
-	ldns_rdf *tmp;
-	bool ip6;
-	ldns_status parse_result;
-
-	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
-	word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
-	addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
-	rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
-	ip6 = false;
-	list = ldns_rr_list_new();
-	rr = NULL;
-	if(!line || !word || !addr || !rr_str || !list) {
-		LDNS_FREE(line);
-		LDNS_FREE(word);
-		LDNS_FREE(addr);
-		LDNS_FREE(rr_str);
-		ldns_rr_list_free(list);
-		return NULL;
-	}
-
-	for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
-			i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
-		/* # is comment */
-		if (line[0] == '#') {
-			continue;
-		}
-		/* put it in a buffer for further processing */
-		linebuf = LDNS_MALLOC(ldns_buffer);
-		if(!linebuf) {
-			LDNS_FREE(line);
-			LDNS_FREE(word);
-			LDNS_FREE(addr);
-			LDNS_FREE(rr_str);
-			ldns_rr_list_deep_free(list);
-			return NULL;
-		}
-
-		ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
-		for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
-				j > 0;
-				j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
-			if (cnt == 0) {
-				/* the address */
-				if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, 
-								word))) {
-					/* ip6 */
-					ldns_rdf_deep_free(tmp);
-					ip6 = true;
-				} else {
-					if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, 
-									word))) {
-						/* ip4 */
-						ldns_rdf_deep_free(tmp);
-						ip6 = false;
-					} else {
-						/* kaput */
-						break;
-					}
-				}
-				(void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
-			} else {
-				/* la al la la */
-				if (ip6) {
-					snprintf(rr_str, LDNS_MAX_LINELEN, 
-						"%s IN AAAA %s", word, addr);
-				} else {
-					snprintf(rr_str, LDNS_MAX_LINELEN, 
-						"%s IN A %s", word, addr);
-				}
-				parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
-				if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
-					ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
-				}
-				ldns_rr_free(rr);
-			}
-		}
-		ldns_buffer_free(linebuf);
-	}
-	LDNS_FREE(line);
-	LDNS_FREE(word);
-	LDNS_FREE(addr);
-	LDNS_FREE(rr_str);
-	return list;
-}
-
-ldns_rr_list *
-ldns_get_rr_list_hosts_frm_file(char *filename)
-{
-	ldns_rr_list *names;
-	FILE *fp;
-
-	if (!filename) {
-                fp = fopen(LDNS_RESOLV_HOSTS, "r");
-        
-        } else {
-                fp = fopen(filename, "r");
-        }
-        if (!fp) {
-                return NULL;
-        }
-
-	names = ldns_get_rr_list_hosts_frm_fp(fp);
-	fclose(fp);
-	return names;
-}
-
-uint16_t
-ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c, 
-		ldns_rr_list **ret)
-{
-	ldns_rdf_type t;
-	uint16_t names_found;
-	ldns_resolver *r;
-	ldns_status s;
-
-	t = ldns_rdf_get_type(node);
-	names_found = 0;
-	r = res;
-
-	if (res == NULL) {
-		/* prepare a new resolver, using /etc/resolv.conf as a guide  */
-		s = ldns_resolver_new_frm_file(&r, NULL);
-		if (s != LDNS_STATUS_OK) {
-			return 0;
-		} 
-	}
-
-	if (t == LDNS_RDF_TYPE_DNAME) {
-		/* we're asked to query for a name */
-		*ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
-		names_found = ldns_rr_list_rr_count(*ret);
-	}
-
-	if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
-		/* an address */
-		*ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
-		names_found = ldns_rr_list_rr_count(*ret);
-	}
-
-	if (res == NULL) {
-		ldns_resolver_deep_free(r);
-	}
-	
-	return names_found;
-}
-
-bool
-ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
-{
-	switch (ldns_rr_get_type(nsec)) {
-	case LDNS_RR_TYPE_NSEC	: if (ldns_rr_rd_count(nsec) < 2) {
-					  return false;
-				  }
-				  return ldns_nsec_bitmap_covers_type(
-						  ldns_rr_rdf(nsec, 1), t);
-
-	case LDNS_RR_TYPE_NSEC3	: if (ldns_rr_rd_count(nsec) < 6) {
-					  return false;
-				  }
-				  return ldns_nsec_bitmap_covers_type(
-						  ldns_rr_rdf(nsec, 5), t);
-
-	default			: return false;
-	}
-}
-
-void
-ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
-{
-	int16_t rdf;
-	ldns_rdf *rd;
-	va_list va_rdf;
-	va_start(va_rdf, rdfnum);
-
-	for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int)) 
-	{
-		rd = ldns_rr_rdf(r, rdf);
-		if (!rd) {
-			continue;
-		} else {
-			ldns_rdf_print(fp, rd);
-			fprintf(fp, " "); /* not sure if we want to do this */
-		}
-	}
-	va_end(va_rdf);
-}
-
diff --git a/src/ldns/host2str.c b/src/ldns/host2str.c
deleted file mode 100644
index 3445254..0000000
--- a/src/ldns/host2str.c
+++ /dev/null
@@ -1,2635 +0,0 @@
-/*
- * host2str.c
- *
- * conversion routines from the host format
- * to the presentation format (strings)
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <limits.h>
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#include <time.h>
-#include <sys/time.h>
-
-#ifndef INET_ADDRSTRLEN
-#define INET_ADDRSTRLEN 16
-#endif
-#ifndef INET6_ADDRSTRLEN
-#define INET6_ADDRSTRLEN 46
-#endif
-
-/* lookup tables for standard DNS stuff  */
-
-/* Taken from RFC 2535, section 7.  */
-ldns_lookup_table ldns_algorithms[] = {
-        { LDNS_RSAMD5, "RSAMD5" },
-        { LDNS_DH, "DH" },
-        { LDNS_DSA, "DSA" },
-        { LDNS_ECC, "ECC" },
-        { LDNS_RSASHA1, "RSASHA1" },
-        { LDNS_DSA_NSEC3, "DSA-NSEC3-SHA1" },
-        { LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
-#ifdef USE_SHA2
-	{ LDNS_RSASHA256, "RSASHA256"},
-	{ LDNS_RSASHA512, "RSASHA512"},
-#endif
-#ifdef USE_GOST
-	{ LDNS_ECC_GOST, "ECC-GOST"},
-#endif
-#ifdef USE_ECDSA
-        { LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
-        { LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
-#endif
-        { LDNS_INDIRECT, "INDIRECT" },
-        { LDNS_PRIVATEDNS, "PRIVATEDNS" },
-        { LDNS_PRIVATEOID, "PRIVATEOID" },
-        { 0, NULL }
-};
-
-/* Taken from RFC 4398  */
-ldns_lookup_table ldns_cert_algorithms[] = {
-        { LDNS_CERT_PKIX, "PKIX" },
-        { LDNS_CERT_SPKI, "SPKI" },
-        { LDNS_CERT_PGP, "PGP" },
-        { LDNS_CERT_IPKIX, "IPKIX" },
-        { LDNS_CERT_ISPKI, "ISPKI" },
-        { LDNS_CERT_IPGP, "IPGP" },
-        { LDNS_CERT_ACPKIX, "ACPKIX" },
-        { LDNS_CERT_IACPKIX, "IACPKIX" },
-        { LDNS_CERT_URI, "URI" },
-        { LDNS_CERT_OID, "OID" },
-        { 0, NULL }
-};
-
-/* classes  */
-ldns_lookup_table ldns_rr_classes[] = {
-        { LDNS_RR_CLASS_IN, "IN" },
-        { LDNS_RR_CLASS_CH, "CH" },
-        { LDNS_RR_CLASS_HS, "HS" },
-        { LDNS_RR_CLASS_NONE, "NONE" },
-        { LDNS_RR_CLASS_ANY, "ANY" },
-        { 0, NULL }
-};
-
-/* if these are used elsewhere */
-ldns_lookup_table ldns_rcodes[] = {
-        { LDNS_RCODE_NOERROR, "NOERROR" },
-        { LDNS_RCODE_FORMERR, "FORMERR" },
-        { LDNS_RCODE_SERVFAIL, "SERVFAIL" },
-        { LDNS_RCODE_NXDOMAIN, "NXDOMAIN" },
-        { LDNS_RCODE_NOTIMPL, "NOTIMPL" },
-        { LDNS_RCODE_REFUSED, "REFUSED" },
-        { LDNS_RCODE_YXDOMAIN, "YXDOMAIN" },
-        { LDNS_RCODE_YXRRSET, "YXRRSET" },
-        { LDNS_RCODE_NXRRSET, "NXRRSET" },
-        { LDNS_RCODE_NOTAUTH, "NOTAUTH" },
-        { LDNS_RCODE_NOTZONE, "NOTZONE" },
-        { 0, NULL }
-};
-
-ldns_lookup_table ldns_opcodes[] = {
-        { LDNS_PACKET_QUERY, "QUERY" },
-        { LDNS_PACKET_IQUERY, "IQUERY" },
-        { LDNS_PACKET_STATUS, "STATUS" },
-	{ LDNS_PACKET_NOTIFY, "NOTIFY" },
-	{ LDNS_PACKET_UPDATE, "UPDATE" },
-        { 0, NULL }
-};
-
-const ldns_output_format   ldns_output_format_nocomments_record = { 0, NULL };
-const ldns_output_format  *ldns_output_format_nocomments 
-			= &ldns_output_format_nocomments_record;
-const ldns_output_format   ldns_output_format_onlykeyids_record = {
-	LDNS_COMMENT_KEY, NULL
-};
-const ldns_output_format  *ldns_output_format_onlykeyids
-			= &ldns_output_format_onlykeyids_record;
-const ldns_output_format  *ldns_output_format_default
-			= &ldns_output_format_onlykeyids_record;
-
-const ldns_output_format   ldns_output_format_bubblebabble_record = { 
-	LDNS_COMMENT_KEY | LDNS_COMMENT_BUBBLEBABBLE | LDNS_COMMENT_FLAGS, NULL
-};
-const ldns_output_format  *ldns_output_format_bubblebabble 
-			= &ldns_output_format_bubblebabble_record;
-
-static bool
-ldns_output_format_covers_type(const ldns_output_format* fmt, ldns_rr_type t)
-{
-	return fmt && (fmt->flags & LDNS_FMT_RFC3597) &&
-		((ldns_output_format_storage*)fmt)->bitmap &&
-		ldns_nsec_bitmap_covers_type(
-				((ldns_output_format_storage*)fmt)->bitmap, t);
-}
-
-ldns_status
-ldns_output_format_set_type(ldns_output_format* fmt, ldns_rr_type t)
-{
-	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
-	ldns_status s;
-	
-	assert(fmt != NULL);
-	
-	if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
-		ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
-	}
-	if (! fmt_st->bitmap) {
-		s = ldns_rdf_bitmap_known_rr_types_space(&fmt_st->bitmap);
-		if (s != LDNS_STATUS_OK) {
-			return s;
-		}
-	}
-	return ldns_nsec_bitmap_set_type(fmt_st->bitmap, t);
-}
-
-ldns_status
-ldns_output_format_clear_type(ldns_output_format* fmt, ldns_rr_type t)
-{
-	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
-	ldns_status s;
-	
-	assert(fmt != NULL);
-
-	if (!(fmt_st->flags & LDNS_FMT_RFC3597)) {
-		ldns_output_format_set(fmt, LDNS_FMT_RFC3597);
-	}
-	if (! fmt_st->bitmap) {
-		s = ldns_rdf_bitmap_known_rr_types(&fmt_st->bitmap);
-		if (s != LDNS_STATUS_OK) {
-			return s;
-		}
-	}
-	return ldns_nsec_bitmap_clear_type(fmt_st->bitmap, t);
-}
-
-ldns_status
-ldns_pkt_opcode2buffer_str(ldns_buffer *output, ldns_pkt_opcode opcode)
-{
-	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode);
-	if (lt && lt->name) {
-		ldns_buffer_printf(output, "%s", lt->name);
-	} else {
-		ldns_buffer_printf(output, "OPCODE%u", opcode);
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_pkt_rcode2buffer_str(ldns_buffer *output, ldns_pkt_rcode rcode)
-{
-	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode);
-	if (lt && lt->name) {
-		ldns_buffer_printf(output, "%s", lt->name);
-	} else {
-		ldns_buffer_printf(output, "RCODE%u", rcode);
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_algorithm2buffer_str(ldns_buffer *output,
-                          ldns_algorithm algorithm)
-{
-	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_algorithms,
-	                                          algorithm);
-	if (lt && lt->name) {
-		ldns_buffer_printf(output, "%s", lt->name);
-	} else {
-		ldns_buffer_printf(output, "ALG%u", algorithm);
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_cert_algorithm2buffer_str(ldns_buffer *output,
-                               ldns_cert_algorithm cert_algorithm)
-{
-	ldns_lookup_table *lt = ldns_lookup_by_id(ldns_cert_algorithms,
-	                                          cert_algorithm);
-	if (lt && lt->name) {
-		ldns_buffer_printf(output, "%s", lt->name);
-	} else {
-		ldns_buffer_printf(output, "CERT_ALG%u",
-		                   cert_algorithm);
-	}
-	return ldns_buffer_status(output);
-}
-
-char *
-ldns_pkt_opcode2str(ldns_pkt_opcode opcode)
-{
-	char *str;
-	ldns_buffer *buf;
-
-	buf = ldns_buffer_new(12);
-	if (!buf) {
-		return NULL;
-	}
-
-	str = NULL;
-	if (ldns_pkt_opcode2buffer_str(buf, opcode) == LDNS_STATUS_OK) {
-		str = ldns_buffer_export2str(buf);
-	}
-
-	ldns_buffer_free(buf);
-	return str;
-}
-
-char *
-ldns_pkt_rcode2str(ldns_pkt_rcode rcode)
-{
-	char *str;
-	ldns_buffer *buf;
-
-	buf = ldns_buffer_new(10);
-	if (!buf) {
-		return NULL;
-	}
-
-	str = NULL;
-	if (ldns_pkt_rcode2buffer_str(buf, rcode) == LDNS_STATUS_OK) {
-		str = ldns_buffer_export2str(buf);
-	}
-
-	ldns_buffer_free(buf);
-	return str;
-}
-
-char *
-ldns_pkt_algorithm2str(ldns_algorithm algorithm)
-{
-	char *str;
-	ldns_buffer *buf;
-
-	buf = ldns_buffer_new(10);
-	if (!buf) {
-		return NULL;
-	}
-
-	str = NULL;
-	if (ldns_algorithm2buffer_str(buf, algorithm)
-	    == LDNS_STATUS_OK) {
-		str = ldns_buffer_export2str(buf);
-	}
-
-	ldns_buffer_free(buf);
-	return str;
-}
-
-char *
-ldns_pkt_cert_algorithm2str(ldns_cert_algorithm cert_algorithm)
-{
-	char *str;
-	ldns_buffer *buf;
-
-	buf = ldns_buffer_new(10);
-	if (!buf) {
-		return NULL;
-	}
-
-	str = NULL;
-	if (ldns_cert_algorithm2buffer_str(buf, cert_algorithm)
-	    == LDNS_STATUS_OK) {
-		str = ldns_buffer_export2str(buf);
-	}
-
-	ldns_buffer_free(buf);
-	return str;
-}
-
-
-/* do NOT pass compressed data here :p */
-ldns_status
-ldns_rdf2buffer_str_dname(ldns_buffer *output, const ldns_rdf *dname)
-{
-	/* can we do with 1 pos var? or without at all? */
-	uint8_t src_pos = 0;
-	uint8_t len;
-	uint8_t *data;
-	uint8_t i;
-	unsigned char c;
-
-	data = (uint8_t*)ldns_rdf_data(dname);
-	len = data[src_pos];
-
-	if (ldns_rdf_size(dname) > LDNS_MAX_DOMAINLEN) {
-		/* too large, return */
-		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
-	}
-
-	/* special case: root label */
-	if (1 == ldns_rdf_size(dname)) {
-		ldns_buffer_printf(output, ".");
-	} else {
-		while ((len > 0) && src_pos < ldns_rdf_size(dname)) {
-			src_pos++;
-			for(i = 0; i < len; i++) {
-				/* paranoia check for various 'strange'
-				   characters in dnames
-				*/
-				c = (unsigned char) data[src_pos];
-				if(c == '.' || c == ';' ||
-				   c == '(' || c == ')' ||
-				   c == '\\') {
-					ldns_buffer_printf(output, "\\%c",
-							data[src_pos]);
-				} else if (!(isascii(c) && isgraph(c))) {
-					ldns_buffer_printf(output, "\\%03u",
-						        data[src_pos]);
-				} else {
-					ldns_buffer_printf(output, "%c", data[src_pos]);
-				}
-				src_pos++;
-			}
-
-			if (src_pos < ldns_rdf_size(dname)) {
-				ldns_buffer_printf(output, ".");
-			}
-			len = data[src_pos];
-		}
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_int8(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	uint8_t data = ldns_rdf_data(rdf)[0];
-	ldns_buffer_printf(output, "%lu", (unsigned long) data);
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_int16(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
-	ldns_buffer_printf(output, "%lu", (unsigned long) data);
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_int32(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	uint32_t data = ldns_read_uint32(ldns_rdf_data(rdf));
-	ldns_buffer_printf(output, "%lu", (unsigned long) data);
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_time(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	/* create a YYYYMMDDHHMMSS string if possible */
-	struct tm tm;
-	char date_buf[16];
-
-	memset(&tm, 0, sizeof(tm));
-	if (ldns_serial_arithmitics_gmtime_r(ldns_rdf2native_int32(rdf), time(NULL), &tm)
-	    && strftime(date_buf, 15, "%Y%m%d%H%M%S", &tm)) {
-		ldns_buffer_printf(output, "%s", date_buf);
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_a(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	char str[INET_ADDRSTRLEN];
-
-	if (inet_ntop(AF_INET, ldns_rdf_data(rdf), str, INET_ADDRSTRLEN)) {
-		ldns_buffer_printf(output, "%s", str);
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_aaaa(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	char str[INET6_ADDRSTRLEN];
-
-	if (inet_ntop(AF_INET6, ldns_rdf_data(rdf), str, INET6_ADDRSTRLEN)) {
-		ldns_buffer_printf(output, "%s", str);
-	}
-
-	return ldns_buffer_status(output);
-}
-
-static void 
-ldns_characters2buffer_str(ldns_buffer* output,
-		size_t amount, const uint8_t* characters)
-{
-	uint8_t ch;
-	while (amount > 0) {
-		ch = *characters++;
-		if (isprint((int)ch) || ch == '\t') {
-			if (ch == '\"' || ch == '\\')
-				ldns_buffer_printf(output, "\\%c", ch);
-			else
-				ldns_buffer_printf(output, "%c", ch);
-		} else {
-			ldns_buffer_printf(output, "\\%03u",
-                                (unsigned)(uint8_t) ch);
-		}
-		amount--;
-	}
-}
-
-ldns_status
-ldns_rdf2buffer_str_str(ldns_buffer *output, const ldns_rdf *rdf)
-{
-        if(ldns_rdf_size(rdf) < 1) {
-                return LDNS_STATUS_WIRE_RDATA_ERR;
-        }
-        if((int)ldns_rdf_size(rdf) < (int)ldns_rdf_data(rdf)[0] + 1) {
-                return LDNS_STATUS_WIRE_RDATA_ERR;
-        }
-	ldns_buffer_printf(output, "\"");
-	ldns_characters2buffer_str(output, 
-			ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf) + 1);
-	ldns_buffer_printf(output, "\"");
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_b64(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	size_t size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf));
-	char *b64 = LDNS_XMALLOC(char, size);
-	if(!b64) return LDNS_STATUS_MEM_ERR;
-	if (ldns_b64_ntop(ldns_rdf_data(rdf), ldns_rdf_size(rdf), b64, size)) {
-		ldns_buffer_printf(output, "%s", b64);
-	}
-	LDNS_FREE(b64);
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_b32_ext(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	size_t size;
-	char *b32;
-	if(ldns_rdf_size(rdf) == 0)
-		return LDNS_STATUS_OK;
-        /* remove -1 for the b32-hash-len octet */
-	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
-        /* add one for the end nul for the string */
-	b32 = LDNS_XMALLOC(char, size + 1);
-	if(!b32) return LDNS_STATUS_MEM_ERR;
-	size = (size_t) ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1,
-		ldns_rdf_size(rdf) - 1, b32, size+1);
-	if (size > 0) {
-		ldns_buffer_printf(output, "%s", b32);
-	}
-	LDNS_FREE(b32);
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_hex(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	size_t i;
-	for (i = 0; i < ldns_rdf_size(rdf); i++) {
-		ldns_buffer_printf(output, "%02x", ldns_rdf_data(rdf)[i]);
-	}
-
-	return ldns_buffer_status(output);
-}
-
-static ldns_status
-ldns_rdf2buffer_str_type_fmt(ldns_buffer *output,
-		const ldns_output_format* fmt, const ldns_rdf *rdf)
-{
-        uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
-
-	if (! ldns_output_format_covers_type(fmt, data) &&
-			ldns_rr_descript(data) &&
-			ldns_rr_descript(data)->_name) {
-
-		ldns_buffer_printf(output, "%s",ldns_rr_descript(data)->_name);
-	} else {
-		ldns_buffer_printf(output, "TYPE%u", data);
-	}
-	return  ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_type(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	return ldns_rdf2buffer_str_type_fmt(output,
-			ldns_output_format_default, rdf);
-}
-
-ldns_status
-ldns_rdf2buffer_str_class(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
-	ldns_lookup_table *lt;
-
- 	lt = ldns_lookup_by_id(ldns_rr_classes, (int) data);
-	if (lt) {
-		ldns_buffer_printf(output, "\t%s", lt->name);
-	} else {
-		ldns_buffer_printf(output, "\tCLASS%d", data);
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_cert_alg(ldns_buffer *output, const ldns_rdf *rdf)
-{
-        uint16_t data = ldns_read_uint16(ldns_rdf_data(rdf));
-	ldns_lookup_table *lt;
- 	lt = ldns_lookup_by_id(ldns_cert_algorithms, (int) data);
-	if (lt) {
-		ldns_buffer_printf(output, "%s", lt->name);
-	} else {
-		ldns_buffer_printf(output, "%d", data);
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_alg(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	return ldns_rdf2buffer_str_int8(output, rdf);
-}
-
-static void
-loc_cm_print(ldns_buffer *output, uint8_t mantissa, uint8_t exponent)
-{
-	uint8_t i;
-	/* is it 0.<two digits> ? */
-	if(exponent < 2) {
-		if(exponent == 1)
-			mantissa *= 10;
-		ldns_buffer_printf(output, "0.%02ld", (long)mantissa);
-		return;
-	}
-	/* always <digit><string of zeros> */
-	ldns_buffer_printf(output, "%d", (int)mantissa);
-	for(i=0; i<exponent-2; i++)
-		ldns_buffer_printf(output, "0");
-}
-
-ldns_status
-ldns_rr_type2buffer_str(ldns_buffer *output, const ldns_rr_type type)
-{
-	const ldns_rr_descriptor *descriptor;
-
-	descriptor = ldns_rr_descript(type);
-
-	switch (type) {
-		case LDNS_RR_TYPE_IXFR:
-			ldns_buffer_printf(output, "IXFR");
-			break;
-		case LDNS_RR_TYPE_AXFR:
-			ldns_buffer_printf(output, "AXFR");
-			break;
-		case LDNS_RR_TYPE_MAILA:
-			ldns_buffer_printf(output, "MAILA");
-			break;
-		case LDNS_RR_TYPE_MAILB:
-			ldns_buffer_printf(output, "MAILB");
-			break;
-		case LDNS_RR_TYPE_ANY:
-			ldns_buffer_printf(output, "ANY");
-			break;
-		default:
-			if (descriptor && descriptor->_name) {
-				ldns_buffer_printf(output, "%s", descriptor->_name);
-			} else {
-				ldns_buffer_printf(output, "TYPE%u", type);
-			}
-	}
-	return ldns_buffer_status(output);
-}
-
-char *
-ldns_rr_type2str(const ldns_rr_type type)
-{
-	char *str;
-	ldns_buffer *buf;
-
-	buf = ldns_buffer_new(10);
-	if (!buf) {
-		return NULL;
-	}
-
-	str = NULL;
-	if (ldns_rr_type2buffer_str(buf, type) == LDNS_STATUS_OK) {
-		str = ldns_buffer_export2str(buf);
-	}
-
-	ldns_buffer_free(buf);
-	return str;
-}
-
-
-ldns_status
-ldns_rr_class2buffer_str(ldns_buffer *output,
-                         const ldns_rr_class klass)
-{
-	ldns_lookup_table *lt;
-
-	lt = ldns_lookup_by_id(ldns_rr_classes, klass);
-	if (lt) {
-		ldns_buffer_printf(output, "%s", lt->name);
-	} else {
-		ldns_buffer_printf(output, "CLASS%d", klass);
-	}
-	return ldns_buffer_status(output);
-}
-
-char *
-ldns_rr_class2str(const ldns_rr_class klass)
-{
-	ldns_buffer *buf;
-	char *str;
-
-	buf = ldns_buffer_new(10);
-	if (!buf) {
-		return NULL;
-	}
-
-	str = NULL;
-	if (ldns_rr_class2buffer_str(buf, klass) == LDNS_STATUS_OK) {
-		str = ldns_buffer_export2str(buf);
-	}
-	ldns_buffer_free(buf);
-	return str;
-}
-
-ldns_status
-ldns_rdf2buffer_str_loc(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	/* we could do checking (ie degrees < 90 etc)? */
-	uint8_t version;
-	uint8_t size;
-	uint8_t horizontal_precision;
-	uint8_t vertical_precision;
-	uint32_t longitude;
-	uint32_t latitude;
-	uint32_t altitude;
-	char northerness;
-	char easterness;
-	uint32_t h;
-	uint32_t m;
-	double s;
-
-	uint32_t equator = (uint32_t) ldns_power(2, 31);
-
-        if(ldns_rdf_size(rdf) < 1) {
-                return LDNS_STATUS_WIRE_RDATA_ERR;
-        }
-       	version = ldns_rdf_data(rdf)[0];
-	if (version == 0) {
-		if(ldns_rdf_size(rdf) < 16) {
-			return LDNS_STATUS_WIRE_RDATA_ERR;
-		}
-		size = ldns_rdf_data(rdf)[1];
-		horizontal_precision = ldns_rdf_data(rdf)[2];
-		vertical_precision = ldns_rdf_data(rdf)[3];
-
-		latitude = ldns_read_uint32(&ldns_rdf_data(rdf)[4]);
-		longitude = ldns_read_uint32(&ldns_rdf_data(rdf)[8]);
-		altitude = ldns_read_uint32(&ldns_rdf_data(rdf)[12]);
-
-		if (latitude > equator) {
-			northerness = 'N';
-			latitude = latitude - equator;
-		} else {
-			northerness = 'S';
-			latitude = equator - latitude;
-		}
-		h = latitude / (1000 * 60 * 60);
-		latitude = latitude % (1000 * 60 * 60);
-		m = latitude / (1000 * 60);
-		latitude = latitude % (1000 * 60);
-		s = (double) latitude / 1000.0;
-		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
-			h, m, s, northerness);
-
-		if (longitude > equator) {
-			easterness = 'E';
-			longitude = longitude - equator;
-		} else {
-			easterness = 'W';
-			longitude = equator - longitude;
-		}
-		h = longitude / (1000 * 60 * 60);
-		longitude = longitude % (1000 * 60 * 60);
-		m = longitude / (1000 * 60);
-		longitude = longitude % (1000 * 60);
-		s = (double) longitude / (1000.0);
-		ldns_buffer_printf(output, "%02u %02u %0.3f %c ",
-			h, m, s, easterness);
-
-
-		s = ((double) altitude) / 100;
-		s -= 100000;
-
-		if(altitude%100 != 0)
-			ldns_buffer_printf(output, "%.2f", s);
-		else
-			ldns_buffer_printf(output, "%.0f", s);
-
-		ldns_buffer_printf(output, "m ");
-
-		loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
-		ldns_buffer_printf(output, "m ");
-
-		loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
-			horizontal_precision & 0x0f);
-		ldns_buffer_printf(output, "m ");
-
-		loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
-			vertical_precision & 0x0f);
-		ldns_buffer_printf(output, "m");
-
-		return ldns_buffer_status(output);
-	} else {
-		return ldns_rdf2buffer_str_hex(output, rdf);
-	}
-}
-
-ldns_status
-ldns_rdf2buffer_str_unknown(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	ldns_buffer_printf(output, "\\# %u ", ldns_rdf_size(rdf));
-	return ldns_rdf2buffer_str_hex(output, rdf);
-}
-
-ldns_status
-ldns_rdf2buffer_str_nsap(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	ldns_buffer_printf(output, "0x");
-	return ldns_rdf2buffer_str_hex(output, rdf);
-}
-
-ldns_status
-ldns_rdf2buffer_str_atma(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	return ldns_rdf2buffer_str_hex(output, rdf);
-}
-
-ldns_status
-ldns_rdf2buffer_str_wks(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	/* protocol, followed by bitmap of services */
-	struct protoent *protocol;
-	char *proto_name = NULL;
-	uint8_t protocol_nr;
-	struct servent *service;
-	uint16_t current_service;
-
-        if(ldns_rdf_size(rdf) < 1) {
-                return LDNS_STATUS_WIRE_RDATA_ERR;
-        }
-	protocol_nr = ldns_rdf_data(rdf)[0];
-	protocol = getprotobynumber((int) protocol_nr);
-	if (protocol && (protocol->p_name != NULL)) {
-		proto_name = protocol->p_name;
-		ldns_buffer_printf(output, "%s ", protocol->p_name);
-	} else {
-		ldns_buffer_printf(output, "%u ", protocol_nr);
-	}
-
-#ifdef HAVE_ENDPROTOENT
-	endprotoent();
-#endif
-
-	for (current_service = 0;
-	     current_service < (ldns_rdf_size(rdf)-1)*8; current_service++) {
-		if (ldns_get_bit(&(ldns_rdf_data(rdf)[1]), current_service)) {
-			service = getservbyport((int) htons(current_service),
-			                        proto_name);
-			if (service && service->s_name) {
-				ldns_buffer_printf(output, "%s ", service->s_name);
-			} else {
-				ldns_buffer_printf(output, "%u ", current_service);
-			}
-#ifdef HAVE_ENDSERVENT
-			endservent();
-#endif
-		}
-	}
-	return ldns_buffer_status(output);
-}
-
-static ldns_status
-ldns_rdf2buffer_str_nsec_fmt(ldns_buffer *output,
-		const ldns_output_format* fmt, const ldns_rdf *rdf)
-{
-	/* Note: this code is duplicated in higher.c in
-	 * ldns_nsec_type_check() function
-	 */
-	uint8_t window_block_nr;
-	uint8_t bitmap_length;
-	uint16_t type;
-	uint16_t pos = 0;
-	uint16_t bit_pos;
-	uint8_t *data = ldns_rdf_data(rdf);
-
-	while((size_t)(pos + 2) < ldns_rdf_size(rdf)) {
-		window_block_nr = data[pos];
-		bitmap_length = data[pos + 1];
-		pos += 2;
-		if (ldns_rdf_size(rdf) < pos + bitmap_length) {
-			return LDNS_STATUS_WIRE_RDATA_ERR;
-		}
-		for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
-			if (! ldns_get_bit(&data[pos], bit_pos)) {
-				continue;
-			}
-			type = 256 * (uint16_t) window_block_nr + bit_pos;
-
-			if (! ldns_output_format_covers_type(fmt, type) &&
-					ldns_rr_descript(type) &&
-					ldns_rr_descript(type)->_name){
-
-				ldns_buffer_printf(output, "%s ",
-						ldns_rr_descript(type)->_name);
-			} else {
-				ldns_buffer_printf(output, "TYPE%u ", type);
-			}
-		}
-		pos += (uint16_t) bitmap_length;
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_nsec(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	return ldns_rdf2buffer_str_nsec_fmt(output,
-			ldns_output_format_default, rdf);
-}
-
-ldns_status
-ldns_rdf2buffer_str_nsec3_salt(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	uint8_t salt_length;
-	uint8_t salt_pos;
-
-	uint8_t *data = ldns_rdf_data(rdf);
-
-        if(ldns_rdf_size(rdf) < 1) {
-                return LDNS_STATUS_WIRE_RDATA_ERR;
-        }
-	salt_length = data[0];
-	/* from now there are variable length entries so remember pos */
-	if (salt_length == 0 || ((size_t)salt_length)+1 > ldns_rdf_size(rdf)) {
-		ldns_buffer_printf(output, "- ");
-	} else {
-		for (salt_pos = 0; salt_pos < salt_length; salt_pos++) {
-			ldns_buffer_printf(output, "%02x", data[1 + salt_pos]);
-		}
-		ldns_buffer_printf(output, " ");
-	}
-
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_period(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	/* period is the number of seconds */
-	if (ldns_rdf_size(rdf) != 4) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	ldns_buffer_printf(output, "%u", ldns_read_uint32(ldns_rdf_data(rdf)));
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_tsigtime(ldns_buffer *output,const  ldns_rdf *rdf)
-{
-	/* tsigtime is 48 bits network order unsigned integer */
-	uint64_t tsigtime = 0;
-	uint8_t *data = ldns_rdf_data(rdf);
-	uint64_t d0, d1, d2, d3, d4, d5;
-
-	if (ldns_rdf_size(rdf) < 6) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	d0 = data[0]; /* cast to uint64 for shift operations */
-	d1 = data[1];
-	d2 = data[2];
-	d3 = data[3];
-	d4 = data[4];
-	d5 = data[5];
-	tsigtime = (d0<<40) | (d1<<32) | (d2<<24) | (d3<<16) | (d4<<8) | d5;
-
-	ldns_buffer_printf(output, "%llu ", (long long)tsigtime);
-
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_apl(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	uint8_t *data = ldns_rdf_data(rdf);
-	uint16_t address_family;
-	uint8_t prefix;
-	bool negation;
-	uint8_t adf_length;
-	size_t i;
-	size_t pos = 0;
-
-	while (pos < (unsigned int) ldns_rdf_size(rdf)) {
-                if(pos + 3 >= (unsigned)ldns_rdf_size(rdf))
-                        return LDNS_STATUS_WIRE_RDATA_ERR;
-		address_family = ldns_read_uint16(&data[pos]);
-		prefix = data[pos + 2];
-		negation = data[pos + 3] & LDNS_APL_NEGATION;
-		adf_length = data[pos + 3] & LDNS_APL_MASK;
-		if (address_family == LDNS_APL_IP4) {
-			/* check if prefix < 32? */
-			if (negation) {
-				ldns_buffer_printf(output, "!");
-			}
-			ldns_buffer_printf(output, "%u:", address_family);
-			/* address is variable length 0 - 4 */
-			for (i = 0; i < 4; i++) {
-				if (i > 0) {
-					ldns_buffer_printf(output, ".");
-				}
-				if (i < (unsigned short) adf_length) {
-                                        if(pos+i+4 >= ldns_rdf_size(rdf))
-					    return LDNS_STATUS_WIRE_RDATA_ERR;
-					ldns_buffer_printf(output, "%d",
-					                   data[pos + i + 4]);
-				} else {
-					ldns_buffer_printf(output, "0");
-				}
-			}
-			ldns_buffer_printf(output, "/%u ", prefix);
-		} else if (address_family == LDNS_APL_IP6) {
-			/* check if prefix < 128? */
-			if (negation) {
-				ldns_buffer_printf(output, "!");
-			}
-			ldns_buffer_printf(output, "%u:", address_family);
-			/* address is variable length 0 - 16 */
-			for (i = 0; i < 16; i++) {
-				if (i % 2 == 0 && i > 0) {
-					ldns_buffer_printf(output, ":");
-				}
-				if (i < (unsigned short) adf_length) {
-                                        if(pos+i+4 >= ldns_rdf_size(rdf))
-					    return LDNS_STATUS_WIRE_RDATA_ERR;
-					ldns_buffer_printf(output, "%02x",
-					                   data[pos + i + 4]);
-				} else {
-					ldns_buffer_printf(output, "00");
-				}
-			}
-			ldns_buffer_printf(output, "/%u ", prefix);
-
-		} else {
-			/* unknown address family */
-			ldns_buffer_printf(output,
-					"Unknown address family: %u data: ",
-					address_family);
-			for (i = 1; i < (unsigned short) (4 + adf_length); i++) {
-                                if(pos+i >= ldns_rdf_size(rdf))
-                                        return LDNS_STATUS_WIRE_RDATA_ERR;
-				ldns_buffer_printf(output, "%02x", data[i]);
-			}
-		}
-		pos += 4 + adf_length;
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_int16_data(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	size_t size;
-	char *b64;
-	if (ldns_rdf_size(rdf) < 2) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	/* Subtract the size (2) of the number that specifies the length */
-	size = ldns_b64_ntop_calculate_size(ldns_rdf_size(rdf) - 2);
-	ldns_buffer_printf(output, "%u ", ldns_rdf_size(rdf) - 2);
-	if (ldns_rdf_size(rdf) > 2) {
-		b64 = LDNS_XMALLOC(char, size);
-		if(!b64)
-			return LDNS_STATUS_MEM_ERR;
-
-		if (ldns_rdf_size(rdf) > 2 &&
-		ldns_b64_ntop(ldns_rdf_data(rdf) + 2,
-					ldns_rdf_size(rdf) - 2,
-					b64, size)) {
-			ldns_buffer_printf(output, "%s", b64);
-		}
-		LDNS_FREE(b64);
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_ipseckey(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	/* wire format from
-	   http://www.ietf.org/internet-drafts/draft-ietf-ipseckey-rr-12.txt
-	*/
-	uint8_t *data = ldns_rdf_data(rdf);
-	uint8_t precedence;
-	uint8_t gateway_type;
-	uint8_t algorithm;
-
-	ldns_rdf *gateway = NULL;
-	uint8_t *gateway_data;
-
-	size_t public_key_size;
-	uint8_t *public_key_data;
-	ldns_rdf *public_key;
-
-	size_t offset = 0;
-	ldns_status status;
-
-	if (ldns_rdf_size(rdf) < 3) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	precedence = data[0];
-	gateway_type = data[1];
-	algorithm = data[2];
-	offset = 3;
-
-	switch (gateway_type) {
-		case 0:
-			/* no gateway */
-			break;
-		case 1:
-			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
-                        if(!gateway_data)
-                                return LDNS_STATUS_MEM_ERR;
-			if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
-				return LDNS_STATUS_ERR;
-			}
-			memcpy(gateway_data, &data[offset], LDNS_IP4ADDRLEN);
-			gateway = ldns_rdf_new(LDNS_RDF_TYPE_A,
-					LDNS_IP4ADDRLEN , gateway_data);
-			offset += LDNS_IP4ADDRLEN;
-                        if(!gateway) {
-                                LDNS_FREE(gateway_data);
-                                return LDNS_STATUS_MEM_ERR;
-                        }
-			break;
-		case 2:
-			gateway_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
-                        if(!gateway_data)
-                                return LDNS_STATUS_MEM_ERR;
-			if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
-				return LDNS_STATUS_ERR;
-			}
-			memcpy(gateway_data, &data[offset], LDNS_IP6ADDRLEN);
-			offset += LDNS_IP6ADDRLEN;
-			gateway =
-				ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
-						LDNS_IP6ADDRLEN, gateway_data);
-                        if(!gateway) {
-                                LDNS_FREE(gateway_data);
-                                return LDNS_STATUS_MEM_ERR;
-                        }
-			break;
-		case 3:
-			status = ldns_wire2dname(&gateway, data,
-					ldns_rdf_size(rdf), &offset);
-                        if(status != LDNS_STATUS_OK)
-                                return status;
-			break;
-		default:
-			/* error? */
-			break;
-	}
-
-	if (ldns_rdf_size(rdf) <= offset) {
-		return LDNS_STATUS_ERR;
-	}
-	public_key_size = ldns_rdf_size(rdf) - offset;
-	public_key_data = LDNS_XMALLOC(uint8_t, public_key_size);
-        if(!public_key_data) {
-                ldns_rdf_free(gateway);
-                return LDNS_STATUS_MEM_ERR;
-        }
-	memcpy(public_key_data, &data[offset], public_key_size);
-	public_key = ldns_rdf_new(LDNS_RDF_TYPE_B64,
-			public_key_size, public_key_data);
-        if(!public_key) {
-                LDNS_FREE(public_key_data);
-                ldns_rdf_free(gateway);
-                return LDNS_STATUS_MEM_ERR;
-        }
-
-	ldns_buffer_printf(output, "%u %u %u ", precedence, gateway_type, algorithm);
-	if (gateway)
-	  	(void) ldns_rdf2buffer_str(output, gateway);
-	else
-		ldns_buffer_printf(output, ".");
-	ldns_buffer_printf(output, " ");
-	(void) ldns_rdf2buffer_str(output, public_key);
-
-	ldns_rdf_free(gateway);
-	ldns_rdf_free(public_key);
-
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_ilnp64(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	if (ldns_rdf_size(rdf) != 8) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	ldns_buffer_printf(output,"%.4x:%.4x:%.4x:%.4x",
-				ldns_read_uint16(ldns_rdf_data(rdf)),
-				ldns_read_uint16(ldns_rdf_data(rdf)+2),
-				ldns_read_uint16(ldns_rdf_data(rdf)+4),
-				ldns_read_uint16(ldns_rdf_data(rdf)+6));
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_eui48(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	if (ldns_rdf_size(rdf) != 6) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
-				ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
-				ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
-				ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5]);
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_eui64(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	if (ldns_rdf_size(rdf) != 8) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	ldns_buffer_printf(output,"%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
-				ldns_rdf_data(rdf)[0], ldns_rdf_data(rdf)[1],
-				ldns_rdf_data(rdf)[2], ldns_rdf_data(rdf)[3],
-				ldns_rdf_data(rdf)[4], ldns_rdf_data(rdf)[5],
-				ldns_rdf_data(rdf)[6], ldns_rdf_data(rdf)[7]);
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_tag(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	size_t nchars;
-	const uint8_t* chars;
-	char ch;
-	if (ldns_rdf_size(rdf) < 2) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	nchars = ldns_rdf_data(rdf)[0];
-	if (nchars >= ldns_rdf_size(rdf) || /* should be rdf_size - 1 */
-			nchars < 1) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	chars = ldns_rdf_data(rdf) + 1;
-	while (nchars > 0) {
-		ch = (char)*chars++;
-		if (! isalnum(ch)) {
-			return LDNS_STATUS_WIRE_RDATA_ERR;
-		}
-		ldns_buffer_printf(output, "%c", ch);
-		nchars--;
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
-{
-
-	ldns_buffer_printf(output, "\"");
-	ldns_characters2buffer_str(output,
-			ldns_rdf_size(rdf), ldns_rdf_data(rdf));
-	ldns_buffer_printf(output, "\"");
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
-{
-	uint8_t *data = ldns_rdf_data(rdf);
-	size_t rdf_size = ldns_rdf_size(rdf);
-	uint8_t hit_size;
-	uint16_t pk_size;
-	int written;
-	
-	if (rdf_size < 6) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	if ((hit_size = data[0]) == 0 ||
-			(pk_size = ldns_read_uint16(data + 2)) == 0 ||
-			rdf_size < (size_t) hit_size + pk_size + 4) {
-
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-
-	ldns_buffer_printf(output, "%d ", (int) data[1]);
-
-	for (data += 4; hit_size > 0; hit_size--, data++) {
-
-		ldns_buffer_printf(output, "%02x", (int) *data);
-	}
-	ldns_buffer_write_u8(output, (uint8_t) ' ');
-
-	if (ldns_buffer_reserve(output,
-				ldns_b64_ntop_calculate_size(pk_size))) {
-
-		written = ldns_b64_ntop(data, pk_size,
-				(char *) ldns_buffer_current(output),
-				ldns_buffer_remaining(output));
-
-		if (written > 0 &&
-				written < (int) ldns_buffer_remaining(output)) {
-
-			output->_position += written;
-		}
-	}
-	return ldns_buffer_status(output);
-}
-
-static ldns_status
-ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
-		const ldns_output_format* fmt, const ldns_rdf *rdf)
-{
-	ldns_status res = LDNS_STATUS_OK;
-
-	/*ldns_buffer_printf(buffer, "%u:", ldns_rdf_get_type(rdf));*/
-	if (rdf) {
-		switch(ldns_rdf_get_type(rdf)) {
-		case LDNS_RDF_TYPE_NONE:
-			break;
-		case LDNS_RDF_TYPE_DNAME:
-			res = ldns_rdf2buffer_str_dname(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_INT8: /* Don't output mnemonics for these */
-		case LDNS_RDF_TYPE_ALG:
-		case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
-		case LDNS_RDF_TYPE_SELECTOR:
-		case LDNS_RDF_TYPE_MATCHING_TYPE:
-			res = ldns_rdf2buffer_str_int8(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_INT16:
-			res = ldns_rdf2buffer_str_int16(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_INT32:
-			res = ldns_rdf2buffer_str_int32(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_PERIOD:
-			res = ldns_rdf2buffer_str_period(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_TSIGTIME:
-			res = ldns_rdf2buffer_str_tsigtime(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_A:
-			res = ldns_rdf2buffer_str_a(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_AAAA:
-			res = ldns_rdf2buffer_str_aaaa(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_STR:
-			res = ldns_rdf2buffer_str_str(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_APL:
-			res = ldns_rdf2buffer_str_apl(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_B32_EXT:
-			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_B64:
-			res = ldns_rdf2buffer_str_b64(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_HEX:
-			res = ldns_rdf2buffer_str_hex(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_NSEC:
-			res = ldns_rdf2buffer_str_nsec_fmt(buffer, fmt, rdf);
-			break;
-		case LDNS_RDF_TYPE_NSEC3_SALT:
-			res = ldns_rdf2buffer_str_nsec3_salt(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_TYPE:
-			res = ldns_rdf2buffer_str_type_fmt(buffer, fmt, rdf);
-			break;
-		case LDNS_RDF_TYPE_CLASS:
-			res = ldns_rdf2buffer_str_class(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_CERT_ALG:
-			res = ldns_rdf2buffer_str_cert_alg(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_UNKNOWN:
-			res = ldns_rdf2buffer_str_unknown(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_TIME:
-			res = ldns_rdf2buffer_str_time(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_HIP:
-			res = ldns_rdf2buffer_str_hip(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_LOC:
-			res = ldns_rdf2buffer_str_loc(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_WKS:
-		case LDNS_RDF_TYPE_SERVICE:
-			res = ldns_rdf2buffer_str_wks(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_NSAP:
-			res = ldns_rdf2buffer_str_nsap(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_ATMA:
-			res = ldns_rdf2buffer_str_atma(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_IPSECKEY:
-			res = ldns_rdf2buffer_str_ipseckey(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_INT16_DATA:
-			res = ldns_rdf2buffer_str_int16_data(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
-			res = ldns_rdf2buffer_str_b32_ext(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_ILNP64:
-			res = ldns_rdf2buffer_str_ilnp64(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_EUI48:
-			res = ldns_rdf2buffer_str_eui48(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_EUI64:
-			res = ldns_rdf2buffer_str_eui64(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_TAG:
-			res = ldns_rdf2buffer_str_tag(buffer, rdf);
-			break;
-		case LDNS_RDF_TYPE_LONG_STR:
-			res = ldns_rdf2buffer_str_long_str(buffer, rdf);
-			break;
-		}
-	} else {
-		/** This will write mangled RRs */
-		ldns_buffer_printf(buffer, "(null) ");
-		res = LDNS_STATUS_ERR;
-	}
-	return res;
-}
-
-ldns_status
-ldns_rdf2buffer_str(ldns_buffer *buffer, const ldns_rdf *rdf)
-{
-	return ldns_rdf2buffer_str_fmt(buffer,ldns_output_format_default,rdf);
-}
-
-static ldns_rdf *
-ldns_b32_ext2dname(const ldns_rdf *rdf)
-{
-	size_t size;
-	char *b32;
-	ldns_rdf *out;
-	if(ldns_rdf_size(rdf) == 0)
-		return NULL;
-        /* remove -1 for the b32-hash-len octet */
-	size = ldns_b32_ntop_calculate_size(ldns_rdf_size(rdf) - 1);
-        /* add one for the end nul for the string */
-	b32 = LDNS_XMALLOC(char, size + 2);
-	if (b32) {
-		if (ldns_b32_ntop_extended_hex(ldns_rdf_data(rdf) + 1, 
-				ldns_rdf_size(rdf) - 1, b32, size+1) > 0) {
-			b32[size] = '.';
-			b32[size+1] = '\0';
-			if (ldns_str2rdf_dname(&out, b32) == LDNS_STATUS_OK) {
-				LDNS_FREE(b32);
-				return out;
-			}
-		}
-		LDNS_FREE(b32);
-	}
-	return NULL;
-}
-
-static ldns_status
-ldns_rr2buffer_str_rfc3597(ldns_buffer *output, const ldns_rr *rr)
-{
-	size_t total_rdfsize = 0;
-	size_t i, j;
-
-	ldns_buffer_printf(output, "TYPE%u\t", ldns_rr_get_type(rr));
-	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-		total_rdfsize += ldns_rdf_size(ldns_rr_rdf(rr, i));
-	}
-	if (total_rdfsize == 0) {
-		ldns_buffer_printf(output, "\\# 0\n");
-		return ldns_buffer_status(output);
-	}
-	ldns_buffer_printf(output, "\\# %d ", total_rdfsize);
-	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-		for (j = 0; j < ldns_rdf_size(ldns_rr_rdf(rr, i)); j++) {
-			ldns_buffer_printf(output, "%.2x",
-					ldns_rdf_data(ldns_rr_rdf(rr, i))[j]);
-		}
-	}
-	ldns_buffer_printf(output, "\n");
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rr2buffer_str_fmt(ldns_buffer *output, 
-		const ldns_output_format *fmt, const ldns_rr *rr)
-{
-	uint16_t i, flags;
-	ldns_status status = LDNS_STATUS_OK;
-	ldns_output_format_storage* fmt_st = (ldns_output_format_storage*)fmt;
-
-	if (fmt_st == NULL) {
-		fmt_st = (ldns_output_format_storage*)
-			  ldns_output_format_default;
-	}
-	if (!rr) {
-		if (LDNS_COMMENT_NULLS & fmt_st->flags) {
-			ldns_buffer_printf(output, "; (null)\n");
-		}
-		return ldns_buffer_status(output);
-	}
-	if (ldns_rr_owner(rr)) {
-		status = ldns_rdf2buffer_str_dname(output, ldns_rr_owner(rr));
-	}
-	if (status != LDNS_STATUS_OK) {
-		return status;
-	}
-
-	/* TTL should NOT be printed if it is a question */
-	if (!ldns_rr_is_question(rr)) {
-		ldns_buffer_printf(output, "\t%d", ldns_rr_ttl(rr));
-	}
-
-	ldns_buffer_printf(output, "\t");
-	status = ldns_rr_class2buffer_str(output, ldns_rr_get_class(rr));
-	if (status != LDNS_STATUS_OK) {
-		return status;
-	}
-	ldns_buffer_printf(output, "\t");
-
-	if (ldns_output_format_covers_type(fmt, ldns_rr_get_type(rr))) {
-		return ldns_rr2buffer_str_rfc3597(output, rr);
-	}
-	status = ldns_rr_type2buffer_str(output, ldns_rr_get_type(rr));
-	if (status != LDNS_STATUS_OK) {
-		return status;
-	}
-
-	if (ldns_rr_rd_count(rr) > 0) {
-		ldns_buffer_printf(output, "\t");
-	} else if (!ldns_rr_is_question(rr)) {
-		ldns_buffer_printf(output, "\t\\# 0");
-	}
-
-	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-		/* ldns_rdf2buffer_str handles NULL input fine! */
-		if ((fmt_st->flags & LDNS_FMT_ZEROIZE_RRSIGS) &&
-				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) &&
-				((/* inception  */ i == 4 &&
-				  ldns_rdf_get_type(ldns_rr_rdf(rr, 4)) == 
-							LDNS_RDF_TYPE_TIME) ||
-				  (/* expiration */ i == 5 &&
-				   ldns_rdf_get_type(ldns_rr_rdf(rr, 5)) ==
-				   			LDNS_RDF_TYPE_TIME) ||
-				  (/* signature  */ i == 8 &&
-				   ldns_rdf_get_type(ldns_rr_rdf(rr, 8)) ==
-				   			LDNS_RDF_TYPE_B64))) {
-
-			ldns_buffer_printf(output, "(null)");
-			status = ldns_buffer_status(output);
-		} else if ((fmt_st->flags & LDNS_FMT_PAD_SOA_SERIAL) &&
-				(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) &&
-				/* serial */ i == 2 &&
-			 	ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) ==
-			 				LDNS_RDF_TYPE_INT32) {
-			ldns_buffer_printf(output, "%10lu",
-				(unsigned long) ldns_read_uint32(
-					ldns_rdf_data(ldns_rr_rdf(rr, 2))));
-			status = ldns_buffer_status(output);
-		} else {
-			status = ldns_rdf2buffer_str_fmt(output,
-					fmt, ldns_rr_rdf(rr, i));
-		}
-		if(status != LDNS_STATUS_OK)
-			return status;
-		if (i < ldns_rr_rd_count(rr) - 1) {
-			ldns_buffer_printf(output, " ");
-		}
-	}
-	/* per RR special comments - handy for DNSSEC types */
-	/* check to prevent question sec. rr from
-	 * getting here */
-	if (ldns_rr_rd_count(rr) > 0) {
-		switch (ldns_rr_get_type(rr)) {
-		case LDNS_RR_TYPE_DNSKEY:
-			/* if ldns_rr_rd_count(rr) > 0
-				then ldns_rr_rdf(rr, 0) exists! */
-			if (! (fmt_st->flags & LDNS_COMMENT_KEY)) {
-				break;
-			}
-			flags = ldns_rdf2native_int16(ldns_rr_rdf(rr, 0));
-			ldns_buffer_printf(output, " ;{");
-			if (fmt_st->flags & LDNS_COMMENT_KEY_ID) {
-				ldns_buffer_printf(output, "id = %u",
-					(unsigned int) ldns_calc_keytag(rr));
-			}
-			if ((fmt_st->flags & LDNS_COMMENT_KEY_TYPE) &&
-					(flags & LDNS_KEY_ZONE_KEY)){
-
-				if (flags & LDNS_KEY_SEP_KEY) {
-					ldns_buffer_printf(output, " (ksk)");
-				} else {
-					ldns_buffer_printf(output, " (zsk)");
-				}
-				if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE){
-					ldns_buffer_printf(output, ", ");
-				}
-			} else if (fmt_st->flags
-					& (LDNS_COMMENT_KEY_ID
-						|LDNS_COMMENT_KEY_SIZE)) {
-				ldns_buffer_printf( output, ", ");
-			}
-			if (fmt_st->flags & LDNS_COMMENT_KEY_SIZE) {
-				ldns_buffer_printf(output, "size = %db",
-					ldns_rr_dnskey_key_size(rr));
-			}
-			ldns_buffer_printf(output, "}");
-			break;
-		case LDNS_RR_TYPE_RRSIG:
-			if ((fmt_st->flags & LDNS_COMMENT_KEY)
-					&& (fmt_st->flags& LDNS_COMMENT_RRSIGS)
-					&& ldns_rr_rdf(rr, 6) != NULL) {
-				ldns_buffer_printf(output, " ;{id = %d}",
-						ldns_rdf2native_int16(
-							ldns_rr_rdf(rr, 6)));
-			}
-			break;
-		case LDNS_RR_TYPE_DS:
-			if ((fmt_st->flags & LDNS_COMMENT_BUBBLEBABBLE) &&
-					ldns_rr_rdf(rr, 3) != NULL) {
-
-				uint8_t *data = ldns_rdf_data(
-						ldns_rr_rdf(rr, 3));
-				size_t len = ldns_rdf_size(ldns_rr_rdf(rr, 3));
-				char *babble = ldns_bubblebabble(data, len);
-				if(babble) {
-					ldns_buffer_printf(output,
-							" ;{%s}", babble);
-				}
-				LDNS_FREE(babble);
-			}
-			break;
-		case LDNS_RR_TYPE_NSEC3:
-			if (! (fmt_st->flags & LDNS_COMMENT_FLAGS) &&
-				! (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN)) {
-				break;
-			}
-			ldns_buffer_printf(output, " ;{");
-			if ((fmt_st->flags & LDNS_COMMENT_FLAGS)) {
-				if (ldns_nsec3_optout(rr)) {
-					ldns_buffer_printf(output,
-						" flags: optout");
-				} else {
-					ldns_buffer_printf(output," flags: -");
-				}
-				if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
-						fmt_st->hashmap != NULL) {
-					ldns_buffer_printf(output, ", ");
-				}
-			}
-			if (fmt_st->flags & LDNS_COMMENT_NSEC3_CHAIN &&
-					fmt_st->hashmap != NULL) {
-				ldns_rbnode_t *node;
-				ldns_rdf *key = ldns_dname_label(
-						ldns_rr_owner(rr), 0);
-				if (key) {
-					node = ldns_rbtree_search(
-						fmt_st->hashmap,
-						(void *) key);
-					if (node->data) {
-						ldns_buffer_printf(output,
-							"from: ");
-						(void) ldns_rdf2buffer_str(
-							output,
-							ldns_dnssec_name_name(
-							   (ldns_dnssec_name*)
-							   node->data
-							));
-					}
-					ldns_rdf_free(key);
-				}
-				key = ldns_b32_ext2dname(
-						ldns_nsec3_next_owner(rr));
-				if (key) {
-					node = ldns_rbtree_search(
-						fmt_st->hashmap,
-						(void *) key);
-					if (node->data) {
-						ldns_buffer_printf(output,
-							" to: ");
-						(void) ldns_rdf2buffer_str(
-							output,
-							ldns_dnssec_name_name(
-							   (ldns_dnssec_name*)
-							   node->data
-							));
-					}
-					ldns_rdf_free(key);
-				}
-			}
-			ldns_buffer_printf(output, "}");
-			break;
-		default:
-			break;
-
-		}
-	}
-	/* last */
-	ldns_buffer_printf(output, "\n");
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rr2buffer_str(ldns_buffer *output, const ldns_rr *rr)
-{
-	return ldns_rr2buffer_str_fmt(output, ldns_output_format_default, rr);
-}
-
-ldns_status
-ldns_rr_list2buffer_str_fmt(ldns_buffer *output, 
-		const ldns_output_format *fmt, const ldns_rr_list *list)
-{
-	uint16_t i;
-
-	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
-		(void) ldns_rr2buffer_str_fmt(output, fmt, 
-				ldns_rr_list_rr(list, i));
-	}
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_rr_list2buffer_str(ldns_buffer *output, const ldns_rr_list *list)
-{
-	return ldns_rr_list2buffer_str_fmt(
-			output, ldns_output_format_default, list);
-}
-
-ldns_status
-ldns_pktheader2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
-{
-	ldns_lookup_table *opcode = ldns_lookup_by_id(ldns_opcodes,
-			                    (int) ldns_pkt_get_opcode(pkt));
-	ldns_lookup_table *rcode = ldns_lookup_by_id(ldns_rcodes,
-			                    (int) ldns_pkt_get_rcode(pkt));
-
-	ldns_buffer_printf(output, ";; ->>HEADER<<- ");
-	if (opcode) {
-		ldns_buffer_printf(output, "opcode: %s, ", opcode->name);
-	} else {
-		ldns_buffer_printf(output, "opcode: ?? (%u), ",
-				ldns_pkt_get_opcode(pkt));
-	}
-	if (rcode) {
-		ldns_buffer_printf(output, "rcode: %s, ", rcode->name);
-	} else {
-		ldns_buffer_printf(output, "rcode: ?? (%u), ", ldns_pkt_get_rcode(pkt));
-	}
-	ldns_buffer_printf(output, "id: %d\n", ldns_pkt_id(pkt));
-	ldns_buffer_printf(output, ";; flags: ");
-
-	if (ldns_pkt_qr(pkt)) {
-		ldns_buffer_printf(output, "qr ");
-	}
-	if (ldns_pkt_aa(pkt)) {
-		ldns_buffer_printf(output, "aa ");
-	}
-	if (ldns_pkt_tc(pkt)) {
-		ldns_buffer_printf(output, "tc ");
-	}
-	if (ldns_pkt_rd(pkt)) {
-		ldns_buffer_printf(output, "rd ");
-	}
-	if (ldns_pkt_cd(pkt)) {
-		ldns_buffer_printf(output, "cd ");
-	}
-	if (ldns_pkt_ra(pkt)) {
-		ldns_buffer_printf(output, "ra ");
-	}
-	if (ldns_pkt_ad(pkt)) {
-		ldns_buffer_printf(output, "ad ");
-	}
-	ldns_buffer_printf(output, "; ");
-	ldns_buffer_printf(output, "QUERY: %u, ", ldns_pkt_qdcount(pkt));
-	ldns_buffer_printf(output, "ANSWER: %u, ", ldns_pkt_ancount(pkt));
-	ldns_buffer_printf(output, "AUTHORITY: %u, ", ldns_pkt_nscount(pkt));
-	ldns_buffer_printf(output, "ADDITIONAL: %u ", ldns_pkt_arcount(pkt));
-	return ldns_buffer_status(output);
-}
-
-ldns_status
-ldns_pkt2buffer_str_fmt(ldns_buffer *output, 
-		const ldns_output_format *fmt, const ldns_pkt *pkt)
-{
-	uint16_t i;
-	ldns_status status = LDNS_STATUS_OK;
-	char *tmp;
-	struct timeval time;
-	time_t time_tt;
-
-	if (!pkt) {
-		ldns_buffer_printf(output, "null");
-		return LDNS_STATUS_OK;
-	}
-
-	if (ldns_buffer_status_ok(output)) {
-		status = ldns_pktheader2buffer_str(output, pkt);
-		if (status != LDNS_STATUS_OK) {
-			return status;
-		}
-
-		ldns_buffer_printf(output, "\n");
-
-		ldns_buffer_printf(output, ";; QUESTION SECTION:\n;; ");
-
-
-		for (i = 0; i < ldns_pkt_qdcount(pkt); i++) {
-			status = ldns_rr2buffer_str_fmt(output, fmt,
-				       ldns_rr_list_rr(
-					       ldns_pkt_question(pkt), i));
-			if (status != LDNS_STATUS_OK) {
-				return status;
-			}
-		}
-		ldns_buffer_printf(output, "\n");
-
-		ldns_buffer_printf(output, ";; ANSWER SECTION:\n");
-		for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
-			status = ldns_rr2buffer_str_fmt(output, fmt,
-				       ldns_rr_list_rr(
-					       ldns_pkt_answer(pkt), i));
-			if (status != LDNS_STATUS_OK) {
-				return status;
-			}
-
-		}
-		ldns_buffer_printf(output, "\n");
-
-		ldns_buffer_printf(output, ";; AUTHORITY SECTION:\n");
-
-		for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
-			status = ldns_rr2buffer_str_fmt(output, fmt,
-				       ldns_rr_list_rr(
-					       ldns_pkt_authority(pkt), i));
-			if (status != LDNS_STATUS_OK) {
-				return status;
-			}
-		}
-		ldns_buffer_printf(output, "\n");
-
-		ldns_buffer_printf(output, ";; ADDITIONAL SECTION:\n");
-		for (i = 0; i < ldns_pkt_arcount(pkt); i++) {
-			status = ldns_rr2buffer_str_fmt(output, fmt,
-				       ldns_rr_list_rr(
-					       ldns_pkt_additional(pkt), i));
-			if (status != LDNS_STATUS_OK) {
-				return status;
-			}
-
-		}
-		ldns_buffer_printf(output, "\n");
-		/* add some futher fields */
-		ldns_buffer_printf(output, ";; Query time: %d msec\n",
-				ldns_pkt_querytime(pkt));
-		if (ldns_pkt_edns(pkt)) {
-			ldns_buffer_printf(output,
-				   ";; EDNS: version %u; flags:",
-				   ldns_pkt_edns_version(pkt));
-			if (ldns_pkt_edns_do(pkt)) {
-				ldns_buffer_printf(output, " do");
-			}
-			/* the extended rcode is the value set, shifted four bits,
-			 * and or'd with the original rcode */
-			if (ldns_pkt_edns_extended_rcode(pkt)) {
-				ldns_buffer_printf(output, " ; ext-rcode: %d",
-					(ldns_pkt_edns_extended_rcode(pkt) << 4 | ldns_pkt_get_rcode(pkt)));
-			}
-			ldns_buffer_printf(output, " ; udp: %u\n",
-					   ldns_pkt_edns_udp_size(pkt));
-
-			if (ldns_pkt_edns_data(pkt)) {
-				ldns_buffer_printf(output, ";; Data: ");
-				(void)ldns_rdf2buffer_str(output,
-							  ldns_pkt_edns_data(pkt));
-				ldns_buffer_printf(output, "\n");
-			}
-		}
-		if (ldns_pkt_tsig(pkt)) {
-			ldns_buffer_printf(output, ";; TSIG:\n;; ");
-			(void) ldns_rr2buffer_str_fmt(
-					output, fmt, ldns_pkt_tsig(pkt));
-			ldns_buffer_printf(output, "\n");
-		}
-		if (ldns_pkt_answerfrom(pkt)) {
-			tmp = ldns_rdf2str(ldns_pkt_answerfrom(pkt));
-			ldns_buffer_printf(output, ";; SERVER: %s\n", tmp);
-			LDNS_FREE(tmp);
-		}
-		time = ldns_pkt_timestamp(pkt);
-		time_tt = (time_t)time.tv_sec;
-		ldns_buffer_printf(output, ";; WHEN: %s",
-				(char*)ctime(&time_tt));
-
-		ldns_buffer_printf(output, ";; MSG SIZE  rcvd: %d\n",
-				(int)ldns_pkt_size(pkt));
-	} else {
-		return ldns_buffer_status(output);
-	}
-	return status;
-}
-
-ldns_status
-ldns_pkt2buffer_str(ldns_buffer *output, const ldns_pkt *pkt)
-{
-	return ldns_pkt2buffer_str_fmt(output, ldns_output_format_default, pkt);
-}
-
-
-#ifdef HAVE_SSL
-static ldns_status
-ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
-{
-	ldns_status status;
-	size_t i;
-	ldns_rdf *b64_bignum;
-
-	ldns_buffer_printf(output, "Key: ");
-
- 	i = ldns_key_hmac_size(k);
-	b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, ldns_key_hmac_key(k));
-	status = ldns_rdf2buffer_str(output, b64_bignum);
-	ldns_rdf_deep_free(b64_bignum);
-	ldns_buffer_printf(output, "\n");
-	return status;
-}
-#endif
-
-#if defined(HAVE_SSL) && defined(USE_GOST)
-static ldns_status
-ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
-{
-	unsigned char* pp = NULL;
-	int ret;
-	ldns_rdf *b64_bignum;
-	ldns_status status;
-
-	ldns_buffer_printf(output, "GostAsn1: ");
-
-	ret = i2d_PrivateKey(p, &pp);
-	b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, (size_t)ret, pp);
-	status = ldns_rdf2buffer_str(output, b64_bignum);
-
-	ldns_rdf_deep_free(b64_bignum);
-	OPENSSL_free(pp);
-	ldns_buffer_printf(output, "\n");
-	return status;
-}
-#endif
-
-ldns_status
-ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
-{
-	ldns_status status = LDNS_STATUS_OK;
-	unsigned char  *bignum;
-#ifdef HAVE_SSL
-#  ifndef S_SPLINT_S
-	uint16_t i;
-#  endif
-	/* not used when ssl is not defined */
-	/*@unused@*/
-	ldns_rdf *b64_bignum = NULL;
-
-	RSA *rsa;
-	DSA *dsa;
-#endif /* HAVE_SSL */
-
-	if (!k) {
-		return LDNS_STATUS_ERR;
-	}
-
-	bignum = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
-	if (!bignum) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (ldns_buffer_status_ok(output)) {
-#ifdef HAVE_SSL
-		switch(ldns_key_algorithm(k)) {
-			case LDNS_SIGN_RSASHA1:
-			case LDNS_SIGN_RSASHA1_NSEC3:
-			case LDNS_SIGN_RSASHA256:
-			case LDNS_SIGN_RSASHA512:
-			case LDNS_SIGN_RSAMD5:
-				/* copied by looking at dnssec-keygen output */
-				/* header */
-				rsa = ldns_key_rsa_key(k);
-
-				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
-				switch(ldns_key_algorithm(k)) {
-				case LDNS_SIGN_RSAMD5:
-					ldns_buffer_printf(output,
-								    "Algorithm: %u (RSA)\n",
-								    LDNS_RSAMD5);
-					break;
-				case LDNS_SIGN_RSASHA1:
-					ldns_buffer_printf(output,
-								    "Algorithm: %u (RSASHA1)\n",
-								    LDNS_RSASHA1);
-					break;
-				case LDNS_SIGN_RSASHA1_NSEC3:
-					ldns_buffer_printf(output,
-								    "Algorithm: %u (RSASHA1_NSEC3)\n",
-								    LDNS_RSASHA1_NSEC3);
-					break;
-#ifdef USE_SHA2
-				case LDNS_SIGN_RSASHA256:
-					ldns_buffer_printf(output,
-								    "Algorithm: %u (RSASHA256)\n",
-								    LDNS_RSASHA256);
-					break;
-				case LDNS_SIGN_RSASHA512:
-					ldns_buffer_printf(output,
-								    "Algorithm: %u (RSASHA512)\n",
-								    LDNS_RSASHA512);
-					break;
-#endif
-				default:
-#ifdef STDERR_MSGS
-					fprintf(stderr, "Warning: unknown signature ");
-					fprintf(stderr,
-						   "algorithm type %u\n",
-						   ldns_key_algorithm(k));
-#endif
-					ldns_buffer_printf(output,
-								    "Algorithm: %u (Unknown)\n",
-								    ldns_key_algorithm(k));
-					break;
-				}
-
-				/* print to buf, convert to bin, convert to b64,
-				 * print to buf */
-				ldns_buffer_printf(output, "Modulus: ");
-#ifndef S_SPLINT_S
-				i = (uint16_t)BN_bn2bin(rsa->n, bignum);
-				if (i > LDNS_MAX_KEYLEN) {
-					goto error;
-				}
-				b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-				if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-					ldns_rdf_deep_free(b64_bignum);
-					goto error;
-				}
-				ldns_rdf_deep_free(b64_bignum);
-				ldns_buffer_printf(output, "\n");
-				ldns_buffer_printf(output, "PublicExponent: ");
-				i = (uint16_t)BN_bn2bin(rsa->e, bignum);
-				if (i > LDNS_MAX_KEYLEN) {
-					goto error;
-				}
-				b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-				if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-					ldns_rdf_deep_free(b64_bignum);
-					goto error;
-				}
-				ldns_rdf_deep_free(b64_bignum);
-				ldns_buffer_printf(output, "\n");
-
-				ldns_buffer_printf(output, "PrivateExponent: ");
-				if (rsa->d) {
-					i = (uint16_t)BN_bn2bin(rsa->d, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					ldns_buffer_printf(output, "(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Prime1: ");
-				if (rsa->p) {
-					i = (uint16_t)BN_bn2bin(rsa->p, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					ldns_buffer_printf(output, "(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Prime2: ");
-				if (rsa->q) {
-					i = (uint16_t)BN_bn2bin(rsa->q, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					ldns_buffer_printf(output, "(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Exponent1: ");
-				if (rsa->dmp1) {
-					i = (uint16_t)BN_bn2bin(rsa->dmp1, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					ldns_buffer_printf(output, "(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Exponent2: ");
-				if (rsa->dmq1) {
-					i = (uint16_t)BN_bn2bin(rsa->dmq1, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					ldns_buffer_printf(output, "(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Coefficient: ");
-				if (rsa->iqmp) {
-					i = (uint16_t)BN_bn2bin(rsa->iqmp, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					ldns_buffer_printf(output, "(Not available)\n");
-				}
-#endif /* splint */
-
-				RSA_free(rsa);
-				break;
-			case LDNS_SIGN_DSA:
-			case LDNS_SIGN_DSA_NSEC3:
-				dsa = ldns_key_dsa_key(k);
-
-				ldns_buffer_printf(output,"Private-key-format: v1.2\n");
-				if (ldns_key_algorithm(k) == LDNS_SIGN_DSA) {
-					ldns_buffer_printf(output,"Algorithm: 3 (DSA)\n");
-				} else if (ldns_key_algorithm(k) == LDNS_SIGN_DSA_NSEC3) {
-					ldns_buffer_printf(output,"Algorithm: 6 (DSA_NSEC3)\n");
-				}
-
-				/* print to buf, convert to bin, convert to b64,
-				 * print to buf */
-				ldns_buffer_printf(output, "Prime(p): ");
-#ifndef S_SPLINT_S
-				if (dsa->p) {
-					i = (uint16_t)BN_bn2bin(dsa->p, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					printf("(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Subprime(q): ");
-				if (dsa->q) {
-					i = (uint16_t)BN_bn2bin(dsa->q, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					printf("(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Base(g): ");
-				if (dsa->g) {
-					i = (uint16_t)BN_bn2bin(dsa->g, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					printf("(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Private_value(x): ");
-				if (dsa->priv_key) {
-					i = (uint16_t)BN_bn2bin(dsa->priv_key, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					printf("(Not available)\n");
-				}
-
-				ldns_buffer_printf(output, "Public_value(y): ");
-				if (dsa->pub_key) {
-					i = (uint16_t)BN_bn2bin(dsa->pub_key, bignum);
-					if (i > LDNS_MAX_KEYLEN) {
-						goto error;
-					}
-					b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-					if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-						goto error;
-					}
-					ldns_rdf_deep_free(b64_bignum);
-					ldns_buffer_printf(output, "\n");
-				} else {
-					printf("(Not available)\n");
-				}
-#endif /* splint */
-				break;
-			case LDNS_SIGN_ECC_GOST:
-				/* no format defined, use blob */
-#if defined(HAVE_SSL) && defined(USE_GOST)
-				ldns_buffer_printf(output, "Private-key-format: v1.2\n");
-				ldns_buffer_printf(output, "Algorithm: %d (ECC-GOST)\n", LDNS_SIGN_ECC_GOST);
-				status = ldns_gost_key2buffer_str(output, 
-#ifndef S_SPLINT_S
-					k->_key.key
-#else
-					NULL
-#endif
-				);
-#else
-				goto error;
-#endif /* GOST */
-				break;
-			case LDNS_SIGN_ECDSAP256SHA256:
-			case LDNS_SIGN_ECDSAP384SHA384:
-#ifdef USE_ECDSA
-                                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
-				ldns_buffer_printf(output, "Algorithm: %d (", ldns_key_algorithm(k));
-                                status=ldns_algorithm2buffer_str(output, (ldns_algorithm)ldns_key_algorithm(k));
-#ifndef S_SPLINT_S
-				ldns_buffer_printf(output, ")\n");
-                                if(k->_key.key) {
-                                        EC_KEY* ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
-                                        const BIGNUM* b = EC_KEY_get0_private_key(ec);
-                                        ldns_buffer_printf(output, "PrivateKey: ");
-                                        i = (uint16_t)BN_bn2bin(b, bignum);
-                                        if (i > LDNS_MAX_KEYLEN) {
-                                                goto error;
-                                        }
-                                        b64_bignum =  ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, i, bignum);
-                                        if (ldns_rdf2buffer_str(output, b64_bignum) != LDNS_STATUS_OK) {
-						ldns_rdf_deep_free(b64_bignum);
-                                                goto error;
-                                        }
-                                        ldns_rdf_deep_free(b64_bignum);
-				        ldns_buffer_printf(output, "\n");
-                                        /* down reference count in EC_KEY
-                                         * its still assigned to the PKEY */
-                                        EC_KEY_free(ec);
-                                }
-#endif /* splint */
-#else
-				goto error;
-#endif /* ECDSA */
-                                break;
-			case LDNS_SIGN_HMACMD5:
-				/* there's not much of a format defined for TSIG */
-				/* It's just a binary blob, Same for all algorithms */
-                ldns_buffer_printf(output, "Private-key-format: v1.2\n");
-                ldns_buffer_printf(output, "Algorithm: 157 (HMAC_MD5)\n");
-				status = ldns_hmac_key2buffer_str(output, k);
-				break;
-			case LDNS_SIGN_HMACSHA1:
-		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
-		        ldns_buffer_printf(output, "Algorithm: 158 (HMAC_SHA1)\n");
-				status = ldns_hmac_key2buffer_str(output, k);
-				break;
-			case LDNS_SIGN_HMACSHA256:
-		        ldns_buffer_printf(output, "Private-key-format: v1.2\n");
-		        ldns_buffer_printf(output, "Algorithm: 159 (HMAC_SHA256)\n");
-				status = ldns_hmac_key2buffer_str(output, k);
-				break;
-		}
-#endif /* HAVE_SSL */
-	} else {
-		LDNS_FREE(bignum);
-		return ldns_buffer_status(output);
-	}
-	LDNS_FREE(bignum);
-	return status;
-
-#ifdef HAVE_SSL
-	/* compiles warn the label isn't used */
-error:
-	LDNS_FREE(bignum);
-	return LDNS_STATUS_ERR;
-#endif /* HAVE_SSL */
-
-}
-
-/*
- * Zero terminate the buffer and copy data.
- */
-char *
-ldns_buffer2str(ldns_buffer *buffer)
-{
-	char *str;
-
-	/* check if buffer ends with \0, if not, and
-	   if there is space, add it */
-	if (*(ldns_buffer_at(buffer, ldns_buffer_position(buffer))) != 0) {
-		if (!ldns_buffer_reserve(buffer, 1)) {
-			return NULL;
-		}
-		ldns_buffer_write_u8(buffer, (uint8_t) '\0');
-		if (!ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer))) {
-			return NULL;
-		}
-	}
-
-	str = strdup((const char *)ldns_buffer_begin(buffer));
-        if(!str) {
-                return NULL;
-        }
-	return str;
-}
-
-/*
- * Zero terminate the buffer and export data.
- */
-char *
-ldns_buffer_export2str(ldns_buffer *buffer)
-{
-	/* Append '\0' as string terminator */
-	if (! ldns_buffer_reserve(buffer, 1)) {
-		return NULL;
-	}
-	ldns_buffer_write_u8(buffer, 0);
-
-	/* reallocate memory to the size of the string and export */
-	ldns_buffer_set_capacity(buffer, ldns_buffer_position(buffer));
-	return ldns_buffer_export(buffer);
-}
-
-char *
-ldns_rdf2str(const ldns_rdf *rdf)
-{
-	char *result = NULL;
-	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-
-	if (!tmp_buffer) {
-		return NULL;
-	}
-	if (ldns_rdf2buffer_str(tmp_buffer, rdf) == LDNS_STATUS_OK) {
-		/* export and return string, destroy rest */
-		result = ldns_buffer_export2str(tmp_buffer);
-	}
-	ldns_buffer_free(tmp_buffer);
-	return result;
-}
-
-char *
-ldns_rr2str_fmt(const ldns_output_format *fmt, const ldns_rr *rr)
-{
-	char *result = NULL;
-	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-
-	if (!tmp_buffer) {
-		return NULL;
-	}
-	if (ldns_rr2buffer_str_fmt(tmp_buffer, fmt, rr)
-		       	== LDNS_STATUS_OK) {
-		/* export and return string, destroy rest */
-		result = ldns_buffer_export2str(tmp_buffer);
-	}
-	ldns_buffer_free(tmp_buffer);
-	return result;
-}
-
-char *
-ldns_rr2str(const ldns_rr *rr)
-{
-	return ldns_rr2str_fmt(ldns_output_format_default, rr);
-}
-
-char *
-ldns_pkt2str_fmt(const ldns_output_format *fmt, const ldns_pkt *pkt)
-{
-	char *result = NULL;
-	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-
-	if (!tmp_buffer) {
-		return NULL;
-	}
-	if (ldns_pkt2buffer_str_fmt(tmp_buffer, fmt, pkt)
-		       	== LDNS_STATUS_OK) {
-		/* export and return string, destroy rest */
-		result = ldns_buffer_export2str(tmp_buffer);
-	}
-
-	ldns_buffer_free(tmp_buffer);
-	return result;
-}
-
-char *
-ldns_pkt2str(const ldns_pkt *pkt)
-{
-	return ldns_pkt2str_fmt(ldns_output_format_default, pkt);
-}
-
-char *
-ldns_key2str(const ldns_key *k)
-{
-	char *result = NULL;
-	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-
-	if (!tmp_buffer) {
-		return NULL;
-	}
-	if (ldns_key2buffer_str(tmp_buffer, k) == LDNS_STATUS_OK) {
-		/* export and return string, destroy rest */
-		result = ldns_buffer_export2str(tmp_buffer);
-	}
-	ldns_buffer_free(tmp_buffer);
-	return result;
-}
-
-char *
-ldns_rr_list2str_fmt(const ldns_output_format *fmt, const ldns_rr_list *list)
-{
-	char *result = NULL;
-	ldns_buffer *tmp_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-
-	if (!tmp_buffer) {
-		return NULL;
-	}
-	if (list) {
-		if (ldns_rr_list2buffer_str_fmt(
-				   tmp_buffer, fmt, list)
-			       	== LDNS_STATUS_OK) {
-		}
-	} else {
-		if (fmt == NULL) {
-			fmt = ldns_output_format_default;
-		}
-		if (fmt->flags & LDNS_COMMENT_NULLS) {
-			ldns_buffer_printf(tmp_buffer, "; (null)\n");
-		}
-	}
-
-	/* export and return string, destroy rest */
-	result = ldns_buffer_export2str(tmp_buffer);
-	ldns_buffer_free(tmp_buffer);
-	return result;
-}
-
-char *
-ldns_rr_list2str(const ldns_rr_list *list)
-{
-	return ldns_rr_list2str_fmt(ldns_output_format_default, list);
-}
-
-void
-ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
-{
-	char *str = ldns_rdf2str(rdf);
-	if (str) {
-		fprintf(output, "%s", str);
-	} else {
-		fprintf(output, ";Unable to convert rdf to string\n");
-	}
-	LDNS_FREE(str);
-}
-
-void
-ldns_rr_print_fmt(FILE *output,
-		const ldns_output_format *fmt, const ldns_rr *rr)
-{
-	char *str = ldns_rr2str_fmt(fmt, rr);
-	if (str) {
-		fprintf(output, "%s", str);
-	} else {
-		fprintf(output, ";Unable to convert rr to string\n");
-	}
-	LDNS_FREE(str);
-}
-
-void
-ldns_rr_print(FILE *output, const ldns_rr *rr)
-{
-	ldns_rr_print_fmt(output, ldns_output_format_default, rr);
-}
-
-void
-ldns_pkt_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_pkt *pkt)
-{
-	char *str = ldns_pkt2str_fmt(fmt, pkt);
-	if (str) {
-		fprintf(output, "%s", str);
-	} else {
-		fprintf(output, ";Unable to convert packet to string\n");
-	}
-	LDNS_FREE(str);
-}
-
-void
-ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
-{
-	ldns_pkt_print_fmt(output, ldns_output_format_default, pkt);
-}
-
-void
-ldns_rr_list_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_rr_list *lst)
-{
-	size_t i;
-	for (i = 0; i < ldns_rr_list_rr_count(lst); i++) {
-		ldns_rr_print_fmt(output, fmt, ldns_rr_list_rr(lst, i));
-	}
-}
-
-void
-ldns_rr_list_print(FILE *output, const ldns_rr_list *lst)
-{
-	ldns_rr_list_print_fmt(output, ldns_output_format_default, lst);
-}
-
-void
-ldns_resolver_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_resolver *r)
-{
-	uint16_t i;
-	ldns_rdf **n;
-	ldns_rdf **s;
-	size_t *rtt;
-	if (!r) {
-		return;
-	}
-	n = ldns_resolver_nameservers(r);
-	s = ldns_resolver_searchlist(r);
-	rtt = ldns_resolver_rtt(r);
-
-	fprintf(output, "port: %d\n", (int)ldns_resolver_port(r));
-	fprintf(output, "edns0 size: %d\n", (int)ldns_resolver_edns_udp_size(r));
-	fprintf(output, "use ip6: %d\n", (int)ldns_resolver_ip6(r));
-
-	fprintf(output, "recursive: %d\n", ldns_resolver_recursive(r));
-	fprintf(output, "usevc: %d\n", ldns_resolver_usevc(r));
-	fprintf(output, "igntc: %d\n", ldns_resolver_igntc(r));
-	fprintf(output, "fail: %d\n", ldns_resolver_fail(r));
-	fprintf(output, "retry: %d\n", (int)ldns_resolver_retry(r));
-	fprintf(output, "retrans: %d\n", (int)ldns_resolver_retrans(r));
-	fprintf(output, "fallback: %d\n", ldns_resolver_fallback(r));
-	fprintf(output, "random: %d\n", ldns_resolver_random(r));
-	fprintf(output, "timeout: %d\n", (int)ldns_resolver_timeout(r).tv_sec);
-	fprintf(output, "dnssec: %d\n", ldns_resolver_dnssec(r));
-	fprintf(output, "dnssec cd: %d\n", ldns_resolver_dnssec_cd(r));
-	fprintf(output, "trust anchors (%d listed):\n",
-		(int)ldns_rr_list_rr_count(ldns_resolver_dnssec_anchors(r)));
-	ldns_rr_list_print_fmt(output, fmt, ldns_resolver_dnssec_anchors(r));
-	fprintf(output, "tsig: %s %s\n",
-                ldns_resolver_tsig_keyname(r)?ldns_resolver_tsig_keyname(r):"-",
-                ldns_resolver_tsig_algorithm(r)?ldns_resolver_tsig_algorithm(r):"-");
-	fprintf(output, "debug: %d\n", ldns_resolver_debug(r));
-
-	fprintf(output, "default domain: ");
-	ldns_rdf_print(output, ldns_resolver_domain(r));
-	fprintf(output, "\n");
-	fprintf(output, "apply default domain: %d\n", ldns_resolver_defnames(r));
-
-	fprintf(output, "searchlist (%d listed):\n",  (int)ldns_resolver_searchlist_count(r));
-	for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
-		fprintf(output, "\t");
-		ldns_rdf_print(output, s[i]);
-		fprintf(output, "\n");
-	}
-	fprintf(output, "apply search list: %d\n", ldns_resolver_dnsrch(r));
-
-	fprintf(output, "nameservers (%d listed):\n", (int)ldns_resolver_nameserver_count(r));
-	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
-		fprintf(output, "\t");
-		ldns_rdf_print(output, n[i]);
-
-		switch ((int)rtt[i]) {
-			case LDNS_RESOLV_RTT_MIN:
-			fprintf(output, " - reachable\n");
-			break;
-			case LDNS_RESOLV_RTT_INF:
-			fprintf(output, " - unreachable\n");
-			break;
-		}
-	}
-}
-
-void
-ldns_resolver_print(FILE *output, const ldns_resolver *r)
-{
-	ldns_resolver_print_fmt(output, ldns_output_format_default, r);
-}
-
-void
-ldns_zone_print_fmt(FILE *output, 
-		const ldns_output_format *fmt, const ldns_zone *z)
-{
-	if(ldns_zone_soa(z))
-		ldns_rr_print_fmt(output, fmt, ldns_zone_soa(z));
-	ldns_rr_list_print_fmt(output, fmt, ldns_zone_rrs(z));
-}
-void
-ldns_zone_print(FILE *output, const ldns_zone *z)
-{
-	ldns_zone_print_fmt(output, ldns_output_format_default, z);
-}
diff --git a/src/ldns/host2wire.c b/src/ldns/host2wire.c
deleted file mode 100644
index 06f45ba..0000000
--- a/src/ldns/host2wire.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * host2wire.c
- *
- * conversion routines from the host to the wire format.
- * This will usually just a re-ordering of the
- * data (as we store it in network format)
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-ldns_status
-ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name)
-{
-	return ldns_dname2buffer_wire_compress(buffer, name, NULL);
-}
-
-ldns_status
-ldns_dname2buffer_wire_compress(ldns_buffer *buffer, const ldns_rdf *name, ldns_rbtree_t *compression_data)
-{
-	ldns_rbnode_t *node;
-	uint8_t *data;
-	size_t size;
-	ldns_rdf *label;
-	ldns_rdf *rest;
-	ldns_status s;
-
-	/* If no tree, just add the data */
-	if(!compression_data)
-	{
-		if (ldns_buffer_reserve(buffer, ldns_rdf_size(name)))
-		{
-			ldns_buffer_write(buffer, ldns_rdf_data(name), ldns_rdf_size(name));
-		}
-		return ldns_buffer_status(buffer);
-	}
-
-	/* No labels left, write final zero */
-	if(ldns_dname_label_count(name)==0)
-	{
-		if(ldns_buffer_reserve(buffer,1))
-		{
-			ldns_buffer_write_u8(buffer, 0);
-		}
-		return ldns_buffer_status(buffer);
-	}
-
-	/* Can we find the name in the tree? */
-	if((node = ldns_rbtree_search(compression_data, ldns_rdf_data(name))) != NULL)
-	{
-		/* Found */
-		uint16_t position = (uint16_t) (intptr_t) node->data | 0xC000;
-		if (ldns_buffer_reserve(buffer, 2))
-		{
-			ldns_buffer_write_u16(buffer, position);
-		}
-		return ldns_buffer_status(buffer);
-	}
-	else
-	{
-		/* Not found. Write cache entry, take off first label, write it, */
-		/* try again with the rest of the name. */
-		ldns_rbnode_t *node = LDNS_MALLOC(ldns_rbnode_t);
-		if(!node)
-		{
-			return LDNS_STATUS_MEM_ERR;
-		}
-		if (ldns_buffer_position(buffer) < 16384) {
-			node->key = strdup((const char *)ldns_rdf_data(name));
-			node->data = (void *) (intptr_t) ldns_buffer_position(buffer);
-			if(!ldns_rbtree_insert(compression_data,node))
-			{
-				/* fprintf(stderr,"Name not found but now it's there?\n"); */
-			}
-		}
-		label = ldns_dname_label(name, 0);
-		rest = ldns_dname_left_chop(name);
-		size = ldns_rdf_size(label) - 1; /* Don't want the final zero */
-		data = ldns_rdf_data(label);
-		if(ldns_buffer_reserve(buffer, size))
-		{
-			ldns_buffer_write(buffer, data, size);
-		}
-		ldns_rdf_deep_free(label);
-		s = ldns_dname2buffer_wire_compress(buffer, rest, compression_data);
-		ldns_rdf_deep_free(rest);
-		return s;
-	}
-}
-
-ldns_status
-ldns_rdf2buffer_wire(ldns_buffer *buffer, const ldns_rdf *rdf)
-{
-	return ldns_rdf2buffer_wire_compress(buffer, rdf, NULL);
-}
-
-ldns_status
-ldns_rdf2buffer_wire_compress(ldns_buffer *buffer, const ldns_rdf *rdf, ldns_rbtree_t *compression_data)
-{
-	/* If it's a DNAME, call that function to get compression */
-	if(compression_data && ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_DNAME)
-	{
-		return ldns_dname2buffer_wire_compress(buffer,rdf,compression_data);
-	}
-
-	if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
-		ldns_buffer_write(buffer, ldns_rdf_data(rdf), ldns_rdf_size(rdf));
-	}
-	return ldns_buffer_status(buffer);
-}
-
-ldns_status
-ldns_rdf2buffer_wire_canonical(ldns_buffer *buffer, const ldns_rdf *rdf)
-{
-	size_t i;
-	uint8_t *rdf_data;
-
-	if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_DNAME) {
-		if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
-			rdf_data = ldns_rdf_data(rdf);
-			for (i = 0; i < ldns_rdf_size(rdf); i++) {
-				ldns_buffer_write_u8(buffer,
-				    (uint8_t) LDNS_DNAME_NORMALIZE((int)rdf_data[i]));
-			}
-		}
-	} else {
-		/* direct copy for all other types */
-		if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
-			ldns_buffer_write(buffer,
-						   ldns_rdf_data(rdf),
-						   ldns_rdf_size(rdf));
-		}
-	}
-	return ldns_buffer_status(buffer);
-}
-
-/* convert a rr list to wireformat */
-ldns_status
-ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list)
-{
-	uint16_t rr_count;
-	uint16_t i;
-
-	rr_count = ldns_rr_list_rr_count(rr_list);
-	for(i = 0; i < rr_count; i++) {
-		(void)ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), 
-					  LDNS_SECTION_ANY);
-	}
-	return ldns_buffer_status(buffer);
-}
-
-
-ldns_status
-ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
-						const ldns_rr *rr,
-						int section)
-{
-	uint16_t i;
-	uint16_t rdl_pos = 0;
-	bool pre_rfc3597 = false;
-	switch (ldns_rr_get_type(rr)) {
-	case LDNS_RR_TYPE_NS:
-	case LDNS_RR_TYPE_MD:
-	case LDNS_RR_TYPE_MF:
-	case LDNS_RR_TYPE_CNAME:
-	case LDNS_RR_TYPE_SOA:
-	case LDNS_RR_TYPE_MB:
-	case LDNS_RR_TYPE_MG:
-	case LDNS_RR_TYPE_MR:
-	case LDNS_RR_TYPE_PTR:
-	case LDNS_RR_TYPE_HINFO:
-	case LDNS_RR_TYPE_MINFO:
-	case LDNS_RR_TYPE_MX:
-	case LDNS_RR_TYPE_RP:
-	case LDNS_RR_TYPE_AFSDB:
-	case LDNS_RR_TYPE_RT:
-	case LDNS_RR_TYPE_SIG:
-	case LDNS_RR_TYPE_PX:
-	case LDNS_RR_TYPE_NXT:
-	case LDNS_RR_TYPE_NAPTR:
-	case LDNS_RR_TYPE_KX:
-	case LDNS_RR_TYPE_SRV:
-	case LDNS_RR_TYPE_DNAME:
-	case LDNS_RR_TYPE_A6:
-	case LDNS_RR_TYPE_RRSIG:
-		pre_rfc3597 = true;
-		break;
-	default:
-		break;
-	}
-	
-	if (ldns_rr_owner(rr)) {
-		(void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_owner(rr));
-	}
-	
-	if (ldns_buffer_reserve(buffer, 4)) {
-		(void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
-		(void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
-	}
-
-	if (section != LDNS_SECTION_QUESTION) {
-		if (ldns_buffer_reserve(buffer, 6)) {
-			ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
-			/* remember pos for later */
-			rdl_pos = ldns_buffer_position(buffer);
-			ldns_buffer_write_u16(buffer, 0);
-		}	
-		for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-			if (pre_rfc3597) {
-				(void) ldns_rdf2buffer_wire_canonical(
-					buffer, ldns_rr_rdf(rr, i));
-			} else {
-				(void) ldns_rdf2buffer_wire(
-					buffer, ldns_rr_rdf(rr, i));
-			}
-		}
-		if (rdl_pos != 0) {
-			ldns_buffer_write_u16_at(buffer, rdl_pos,
-			                         ldns_buffer_position(buffer)
-		        	                   - rdl_pos - 2);
-		}
-	}
-	return ldns_buffer_status(buffer);
-}
-
-ldns_status
-ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
-{
-	return ldns_rr2buffer_wire_compress(buffer,rr,section,NULL);
-}
-
-ldns_status
-ldns_rr2buffer_wire_compress(ldns_buffer *buffer, const ldns_rr *rr, int section, ldns_rbtree_t *compression_data)
-{
-	uint16_t i;
-	uint16_t rdl_pos = 0;
-
-	if (ldns_rr_owner(rr)) {
-		(void) ldns_dname2buffer_wire_compress(buffer, ldns_rr_owner(rr), compression_data);
-	}
-	
-	if (ldns_buffer_reserve(buffer, 4)) {
-		(void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
-		(void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
-	}
-
-	if (section != LDNS_SECTION_QUESTION) {
-		if (ldns_buffer_reserve(buffer, 6)) {
-			ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
-			/* remember pos for later */
-			rdl_pos = ldns_buffer_position(buffer);
-			ldns_buffer_write_u16(buffer, 0);
-		}
-		if (LDNS_RR_COMPRESS ==
-		    ldns_rr_descript(ldns_rr_get_type(rr))->_compress) {
-
-			for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-				(void) ldns_rdf2buffer_wire_compress(buffer,
-				    ldns_rr_rdf(rr, i), compression_data);
-			}
-		} else {
-			for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-				(void) ldns_rdf2buffer_wire(
-				    buffer, ldns_rr_rdf(rr, i));
-			}
-		}
-		if (rdl_pos != 0) {
-			ldns_buffer_write_u16_at(buffer, rdl_pos,
-			                         ldns_buffer_position(buffer)
-		        	                   - rdl_pos - 2);
-		}
-	}
-	return ldns_buffer_status(buffer);
-}
-
-ldns_status
-ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
-{
-	uint16_t i;
-
-	/* it must be a sig RR */
-	if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
-		return LDNS_STATUS_ERR;
-	}
-	
-	/* Convert all the rdfs, except the actual signature data
-	 * rdf number 8  - the last, hence: -1 */
-	for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
-		(void) ldns_rdf2buffer_wire_canonical(buffer, 
-				ldns_rr_rdf(rr, i));
-	}
-
-	return ldns_buffer_status(buffer);
-}
-
-ldns_status
-ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
-{
-	uint16_t i;
-
-	/* convert all the rdf's */
-	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-		(void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr,i));
-	}
-	return ldns_buffer_status(buffer);
-}
-
-/*
- * Copies the packet header data to the buffer in wire format
- */
-static ldns_status
-ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
-{
-	uint8_t flags;
-	uint16_t arcount;
-
-	if (ldns_buffer_reserve(buffer, 12)) {
-		ldns_buffer_write_u16(buffer, ldns_pkt_id(packet));
-		
-		flags = ldns_pkt_qr(packet) << 7
-		        | ldns_pkt_get_opcode(packet) << 3
-		        | ldns_pkt_aa(packet) << 2
-		        | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet);
-		ldns_buffer_write_u8(buffer, flags);
-		
-		flags = ldns_pkt_ra(packet) << 7
-		        /*| ldns_pkt_z(packet) << 6*/
-		        | ldns_pkt_ad(packet) << 5
-		        | ldns_pkt_cd(packet) << 4
-			| ldns_pkt_get_rcode(packet);
-		ldns_buffer_write_u8(buffer, flags);
-		
-		ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet));
-		ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet));
-		ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet));
-		/* add EDNS0 and TSIG to additional if they are there */
-		arcount = ldns_pkt_arcount(packet);
-		if (ldns_pkt_tsig(packet)) {
-			arcount++;
-		}
-		if (ldns_pkt_edns(packet)) {
-			arcount++;
-		}
-		ldns_buffer_write_u16(buffer, arcount);
-	}
-	
-	return ldns_buffer_status(buffer);
-}
-
-void
-compression_node_free(ldns_rbnode_t *node, void *arg)
-{
-	(void)arg; /* Yes, dear compiler, it is used */
-	free((void *)node->key);
-	LDNS_FREE(node);
-}
-
-ldns_status
-ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
-{
-	ldns_rr_list *rr_list;
-	uint16_t i;
-
-	/* edns tmp vars */
-	ldns_rr *edns_rr;
-	uint8_t edata[4];
-
-	ldns_rbtree_t *compression_data = ldns_rbtree_create((int (*)(const void *, const void *))strcasecmp);
-	
-	(void) ldns_hdr2buffer_wire(buffer, packet);
-
-	rr_list = ldns_pkt_question(packet);
-	if (rr_list) {
-		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
-			(void) ldns_rr2buffer_wire_compress(buffer, 
-			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION, compression_data);
-		}
-	}
-	rr_list = ldns_pkt_answer(packet);
-	if (rr_list) {
-		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
-			(void) ldns_rr2buffer_wire_compress(buffer, 
-			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER, compression_data);
-		}
-	}
-	rr_list = ldns_pkt_authority(packet);
-	if (rr_list) {
-		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
-			(void) ldns_rr2buffer_wire_compress(buffer, 
-			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY, compression_data);
-		}
-	}
-	rr_list = ldns_pkt_additional(packet);
-	if (rr_list) {
-		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
-			(void) ldns_rr2buffer_wire_compress(buffer, 
-			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL, compression_data);
-		}
-	}
-	
-	/* add EDNS to additional if it is needed */
-	if (ldns_pkt_edns(packet)) {
-		edns_rr = ldns_rr_new();
-		if(!edns_rr) return LDNS_STATUS_MEM_ERR;
-		ldns_rr_set_owner(edns_rr,
-				ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
-		ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
-		ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
-		edata[0] = ldns_pkt_edns_extended_rcode(packet);
-		edata[1] = ldns_pkt_edns_version(packet);
-		ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
-		ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
-		/* don't forget to add the edns rdata (if any) */
-		if (packet->_edns_data)
-			ldns_rr_push_rdf (edns_rr, packet->_edns_data);
-		(void)ldns_rr2buffer_wire_compress(buffer, edns_rr, LDNS_SECTION_ADDITIONAL, compression_data);
-		/* take the edns rdata back out of the rr before we free rr */
-		if (packet->_edns_data)
-			(void)ldns_rr_pop_rdf (edns_rr);
-		ldns_rr_free(edns_rr);
-	}
-	
-	/* add TSIG to additional if it is there */
-	if (ldns_pkt_tsig(packet)) {
-		(void) ldns_rr2buffer_wire_compress(buffer,
-		                           ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL, compression_data);
-	}
-
-	ldns_traverse_postorder(compression_data,compression_node_free,NULL);
-	ldns_rbtree_free(compression_data);
-
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
-{
-	ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	ldns_status status;
-	*result_size = 0;
-	*dest = NULL;
-	if(!buffer) return LDNS_STATUS_MEM_ERR;
-	
-	status = ldns_rdf2buffer_wire(buffer, rdf);
-	if (status == LDNS_STATUS_OK) {
-		*result_size =  ldns_buffer_position(buffer);
-		*dest = (uint8_t *) ldns_buffer_export(buffer);
-	}
-	ldns_buffer_free(buffer);
-	return status;
-}
-
-ldns_status
-ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size)
-{
-	ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	ldns_status status;
-	*result_size = 0;
-	*dest = NULL;
-	if(!buffer) return LDNS_STATUS_MEM_ERR;
-	
-	status = ldns_rr2buffer_wire(buffer, rr, section);
-	if (status == LDNS_STATUS_OK) {
-		*result_size =  ldns_buffer_position(buffer);
-		*dest = (uint8_t *) ldns_buffer_export(buffer);
-	}
-	ldns_buffer_free(buffer);
-	return status;
-}
-
-ldns_status
-ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
-{
-	ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	ldns_status status;
-	*result_size = 0;
-	*dest = NULL;
-	if(!buffer) return LDNS_STATUS_MEM_ERR;
-	
-	status = ldns_pkt2buffer_wire(buffer, packet);
-	if (status == LDNS_STATUS_OK) {
-		*result_size =  ldns_buffer_position(buffer);
-		*dest = (uint8_t *) ldns_buffer_export(buffer);
-	}
-	ldns_buffer_free(buffer);
-	return status;
-}
diff --git a/src/ldns/keys.c b/src/ldns/keys.c
deleted file mode 100644
index 8b43821..0000000
--- a/src/ldns/keys.c
+++ /dev/null
@@ -1,1726 +0,0 @@
-/*
- * keys.c handle private keys for use in DNSSEC
- *
- * This module should hide some of the openSSL complexities
- * and give a general interface for private keys and hmac
- * handling
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#ifdef HAVE_SSL
-#include <openssl/ssl.h>
-#include <openssl/engine.h>
-#include <openssl/rand.h>
-#endif /* HAVE_SSL */
-
-ldns_lookup_table ldns_signing_algorithms[] = {
-        { LDNS_SIGN_RSAMD5, "RSAMD5" },
-        { LDNS_SIGN_RSASHA1, "RSASHA1" },
-        { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
-#ifdef USE_SHA2
-        { LDNS_SIGN_RSASHA256, "RSASHA256" },
-        { LDNS_SIGN_RSASHA512, "RSASHA512" },
-#endif
-#ifdef USE_GOST
-        { LDNS_SIGN_ECC_GOST, "ECC-GOST" },
-#endif
-#ifdef USE_ECDSA
-        { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" },
-        { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" },
-#endif
-        { LDNS_SIGN_DSA, "DSA" },
-        { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" },
-        { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
-        { LDNS_SIGN_HMACSHA1, "hmac-sha1" },
-        { LDNS_SIGN_HMACSHA256, "hmac-sha256" },
-        { 0, NULL }
-};
-
-ldns_key_list *
-ldns_key_list_new(void)
-{
-	ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list);
-	if (!key_list) {
-		return NULL;
-	} else {
-		key_list->_key_count = 0;
-		key_list->_keys = NULL;
-		return key_list;
-	}
-}
-
-ldns_key *
-ldns_key_new(void)
-{
-	ldns_key *newkey;
-
-	newkey = LDNS_MALLOC(ldns_key);
-	if (!newkey) {
-		return NULL;
-	} else {
-		/* some defaults - not sure wether to do this */
-		ldns_key_set_use(newkey, true);
-		ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY);
-		ldns_key_set_origttl(newkey, 0);
-		ldns_key_set_keytag(newkey, 0);
-		ldns_key_set_inception(newkey, 0);
-		ldns_key_set_expiration(newkey, 0);
-		ldns_key_set_pubkey_owner(newkey, NULL);
-#ifdef HAVE_SSL
-		ldns_key_set_evp_key(newkey, NULL);
-#endif /* HAVE_SSL */
-		ldns_key_set_hmac_key(newkey, NULL);
-		ldns_key_set_external_key(newkey, NULL);
-		return newkey;
-	}
-}
-
-ldns_status
-ldns_key_new_frm_fp(ldns_key **k, FILE *fp)
-{
-	return ldns_key_new_frm_fp_l(k, fp, NULL);
-}
-
-#ifdef HAVE_SSL
-ldns_status
-ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
-{
-	ldns_key *k;
-
-	k = ldns_key_new();
-        if(!k) return LDNS_STATUS_MEM_ERR;
-#ifndef S_SPLINT_S
-	k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL);
-        if(!k->_key.key) {
-                ldns_key_free(k);
-                return LDNS_STATUS_ERR;
-        }
-	ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg);
-	if (!k->_key.key) {
-                ldns_key_free(k);
-		return LDNS_STATUS_ENGINE_KEY_NOT_LOADED;
-	} 
-#endif /* splint */
-	*key = k;
-	return LDNS_STATUS_OK;
-}
-#endif
-
-#ifdef USE_GOST
-/** store GOST engine reference loaded into OpenSSL library */
-ENGINE* ldns_gost_engine = NULL;
-
-int
-ldns_key_EVP_load_gost_id(void)
-{
-	static int gost_id = 0;
-	const EVP_PKEY_ASN1_METHOD* meth;
-	ENGINE* e;
-
-	if(gost_id) return gost_id;
-
-	/* see if configuration loaded gost implementation from other engine*/
-	meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
-	if(meth) {
-		EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
-		return gost_id;
-	}
-
-	/* see if engine can be loaded already */
-	e = ENGINE_by_id("gost");
-	if(!e) {
-		/* load it ourself, in case statically linked */
-		ENGINE_load_builtin_engines();
-		ENGINE_load_dynamic();
-		e = ENGINE_by_id("gost");
-	}
-	if(!e) {
-		/* no gost engine in openssl */
-		return 0;
-	}
-	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
-		ENGINE_finish(e);
-		ENGINE_free(e);
-		return 0;
-	}
-
-	meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
-	if(!meth) {
-		/* algo not found */
-		ENGINE_finish(e);
-		ENGINE_free(e);
-		return 0;
-	}
-        /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
-         * on some platforms this frees up the meth and unloads gost stuff */
-        ldns_gost_engine = e;
-	
-	EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
-	return gost_id;
-} 
-
-void ldns_key_EVP_unload_gost(void)
-{
-        if(ldns_gost_engine) {
-                ENGINE_finish(ldns_gost_engine);
-                ENGINE_free(ldns_gost_engine);
-                ldns_gost_engine = NULL;
-        }
-}
-
-/** read GOST private key */
-static EVP_PKEY*
-ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr)
-{
-	char token[16384];
-	const unsigned char* pp;
-	int gost_id;
-	EVP_PKEY* pkey;
-	ldns_rdf* b64rdf = NULL;
-
-	gost_id = ldns_key_EVP_load_gost_id();
-	if(!gost_id)
-		return NULL;
-
-	if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n", 
-		sizeof(token), line_nr) == -1)
-		return NULL;
-	while(strlen(token) < 96) {
-		/* read more b64 from the file, b64 split on multiple lines */
-		if(ldns_fget_token_l(fp, token+strlen(token), "\n",
-			sizeof(token)-strlen(token), line_nr) == -1)
-			return NULL;
-	}
-	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
-		return NULL;
-	pp = (unsigned char*)ldns_rdf_data(b64rdf);
-	pkey = d2i_PrivateKey(gost_id, NULL, &pp, (int)ldns_rdf_size(b64rdf));
-	ldns_rdf_deep_free(b64rdf);
-	return pkey;
-}
-#endif
-
-#ifdef USE_ECDSA
-/** calculate public key from private key */
-static int
-ldns_EC_KEY_calc_public(EC_KEY* ec)
-{
-        EC_POINT* pub_key;
-        const EC_GROUP* group;
-        group = EC_KEY_get0_group(ec);
-        pub_key = EC_POINT_new(group);
-        if(!pub_key) return 0;
-        if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
-                EC_POINT_free(pub_key);
-                return 0;
-        }
-        if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec),
-                NULL, NULL, NULL)) {
-                EC_POINT_free(pub_key);
-                return 0;
-        }
-        if(EC_KEY_set_public_key(ec, pub_key) == 0) {
-                EC_POINT_free(pub_key);
-                return 0;
-        }
-        EC_POINT_free(pub_key);
-        return 1;
-}
-
-/** read ECDSA private key */
-static EVP_PKEY*
-ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
-{
-	char token[16384];
-        ldns_rdf* b64rdf = NULL;
-        unsigned char* pp;
-        BIGNUM* bn;
-        EVP_PKEY* evp_key;
-        EC_KEY* ec;
-	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 
-		sizeof(token), line_nr) == -1)
-		return NULL;
-	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
-		return NULL;
-        pp = (unsigned char*)ldns_rdf_data(b64rdf);
-
-        if(alg == LDNS_ECDSAP256SHA256)
-                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
-        else if(alg == LDNS_ECDSAP384SHA384)
-                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
-        else    ec = NULL;
-        if(!ec) {
-	        ldns_rdf_deep_free(b64rdf);
-                return NULL;
-        }
-	bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL);
-	ldns_rdf_deep_free(b64rdf);
-        if(!bn) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-        EC_KEY_set_private_key(ec, bn);
-        BN_free(bn);
-        if(!ldns_EC_KEY_calc_public(ec)) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-
-        evp_key = EVP_PKEY_new();
-        if(!evp_key) {
-                EC_KEY_free(ec);
-                return NULL;
-        }
-        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
-		EVP_PKEY_free(evp_key);
-                EC_KEY_free(ec);
-                return NULL;
-	}
-        return evp_key;
-}
-#endif
-	
-ldns_status
-ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
-{
-	ldns_key *k;
-	char *d;
-	ldns_signing_algorithm alg;
-	ldns_rr *key_rr;
-#ifdef HAVE_SSL
-	RSA *rsa;
-	DSA *dsa;
-	unsigned char *hmac;
-	size_t hmac_size;
-#endif /* HAVE_SSL */
-
-	k = ldns_key_new();
-
-	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
-	if (!k || !d) {
-                ldns_key_free(k);
-                LDNS_FREE(d);
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	alg = 0;
-
-	/* the file is highly structured. Do this in sequence */
-	/* RSA:
-	 * Private-key-format: v1.x.
- 	 * Algorithm: 1 (RSA)
-
-	 */
-	/* get the key format version number */
-	if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n",
-				LDNS_MAX_LINELEN, line_nr) == -1) {
-		/* no version information */
-                ldns_key_free(k);
-                LDNS_FREE(d);
-		return LDNS_STATUS_SYNTAX_ERR;
-	}
-	if (strncmp(d, "v1.", 3) != 0) {
-                ldns_key_free(k);
-                LDNS_FREE(d);
-		return LDNS_STATUS_SYNTAX_VERSION_ERR;
-	}
-
-	/* get the algorithm type, our file function strip ( ) so there are
-	 * not in the return string! */
-	if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n",
-				LDNS_MAX_LINELEN, line_nr) == -1) {
-		/* no alg information */
-                ldns_key_free(k);
-                LDNS_FREE(d);
-		return LDNS_STATUS_SYNTAX_ALG_ERR;
-	}
-
-	if (strncmp(d, "1 RSA", 2) == 0) {
-		alg = LDNS_SIGN_RSAMD5;
-	}
-	if (strncmp(d, "2 DH", 2) == 0) {
-		alg = (ldns_signing_algorithm)LDNS_DH;
-	}
-	if (strncmp(d, "3 DSA", 2) == 0) {
-		alg = LDNS_SIGN_DSA;
-	}
-	if (strncmp(d, "4 ECC", 2) == 0) {
-		alg = (ldns_signing_algorithm)LDNS_ECC;
-	}
-	if (strncmp(d, "5 RSASHA1", 2) == 0) {
-		alg = LDNS_SIGN_RSASHA1;
-	}
-	if (strncmp(d, "6 DSA", 2) == 0) {
-		alg = LDNS_SIGN_DSA_NSEC3;
-	}
-	if (strncmp(d, "7 RSASHA1", 2) == 0) {
-		alg = LDNS_SIGN_RSASHA1_NSEC3;
-	}
-
-	if (strncmp(d, "8 RSASHA256", 2) == 0) {
-#ifdef USE_SHA2
-		alg = LDNS_SIGN_RSASHA256;
-#else
-# ifdef STDERR_MSGS
-		fprintf(stderr, "Warning: SHA256 not compiled into this ");
-		fprintf(stderr, "version of ldns\n");
-# endif
-#endif
-	}
-	if (strncmp(d, "10 RSASHA512", 3) == 0) {
-#ifdef USE_SHA2
-		alg = LDNS_SIGN_RSASHA512;
-#else
-# ifdef STDERR_MSGS
-		fprintf(stderr, "Warning: SHA512 not compiled into this ");
-		fprintf(stderr, "version of ldns\n");
-# endif
-#endif
-	}
-	if (strncmp(d, "12 ECC-GOST", 3) == 0) {
-#ifdef USE_GOST
-		alg = LDNS_SIGN_ECC_GOST;
-#else
-# ifdef STDERR_MSGS
-		fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
-		fprintf(stderr, "version of ldns, use --enable-gost\n");
-# endif
-#endif
-	}
-	if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
-#ifdef USE_ECDSA
-                alg = LDNS_SIGN_ECDSAP256SHA256;
-#else
-# ifdef STDERR_MSGS
-		fprintf(stderr, "Warning: ECDSA not compiled into this ");
-		fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
-# endif
-#endif
-        }
-	if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
-#ifdef USE_ECDSA
-                alg = LDNS_SIGN_ECDSAP384SHA384;
-#else
-# ifdef STDERR_MSGS
-		fprintf(stderr, "Warning: ECDSA not compiled into this ");
-		fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
-# endif
-#endif
-        }
-	if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
-		alg = LDNS_SIGN_HMACMD5;
-	}
-	if (strncmp(d, "158 HMAC-SHA1", 4) == 0) {
-		alg = LDNS_SIGN_HMACSHA1;
-	}
-	if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
-		alg = LDNS_SIGN_HMACSHA256;
-	}
-
-	LDNS_FREE(d);
-
-	switch(alg) {
-		case LDNS_SIGN_RSAMD5:
-		case LDNS_SIGN_RSASHA1:
-		case LDNS_SIGN_RSASHA1_NSEC3:
-#ifdef USE_SHA2
-		case LDNS_SIGN_RSASHA256:
-		case LDNS_SIGN_RSASHA512:
-#endif
-			ldns_key_set_algorithm(k, alg);
-#ifdef HAVE_SSL
-			rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
-			if (!rsa) {
-				ldns_key_free(k);
-				return LDNS_STATUS_ERR;
-			}
-			ldns_key_assign_rsa_key(k, rsa);
-#endif /* HAVE_SSL */
-			break;
-		case LDNS_SIGN_DSA:
-		case LDNS_SIGN_DSA_NSEC3:
-			ldns_key_set_algorithm(k, alg);
-#ifdef HAVE_SSL
-			dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
-			if (!dsa) {
-				ldns_key_free(k);
-				return LDNS_STATUS_ERR;
-			}
-			ldns_key_assign_dsa_key(k, dsa);
-#endif /* HAVE_SSL */
-			break;
-		case LDNS_SIGN_HMACMD5:
-		case LDNS_SIGN_HMACSHA1:
-		case LDNS_SIGN_HMACSHA256:
-			ldns_key_set_algorithm(k, alg);
-#ifdef HAVE_SSL
-			hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
-			if (!hmac) {
-				ldns_key_free(k);
-				return LDNS_STATUS_ERR;
-			}
-			ldns_key_set_hmac_size(k, hmac_size);
-			ldns_key_set_hmac_key(k, hmac);
-#endif /* HAVE_SSL */
-			break;
-		case LDNS_SIGN_ECC_GOST:
-			ldns_key_set_algorithm(k, alg);
-#if defined(HAVE_SSL) && defined(USE_GOST)
-                        if(!ldns_key_EVP_load_gost_id()) {
-				ldns_key_free(k);
-                                return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
-                        }
-			ldns_key_set_evp_key(k, 
-				ldns_key_new_frm_fp_gost_l(fp, line_nr));
-#ifndef S_SPLINT_S
-			if(!k->_key.key) {
-				ldns_key_free(k);
-				return LDNS_STATUS_ERR;
-			}
-#endif /* splint */
-#endif
-			break;
-#ifdef USE_ECDSA
-               case LDNS_SIGN_ECDSAP256SHA256:
-               case LDNS_SIGN_ECDSAP384SHA384:
-                        ldns_key_set_algorithm(k, alg);
-                        ldns_key_set_evp_key(k,
-                                ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr));
-#ifndef S_SPLINT_S
-			if(!k->_key.key) {
-				ldns_key_free(k);
-				return LDNS_STATUS_ERR;
-			}
-#endif /* splint */
-			break;
-#endif
-		default:
-			ldns_key_free(k);
-			return LDNS_STATUS_SYNTAX_ALG_ERR;
-	}
-	key_rr = ldns_key2rr(k);
-	ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
-	ldns_rr_free(key_rr);
-
-	if (key) {
-		*key = k;
-		return LDNS_STATUS_OK;
-	}
-	ldns_key_free(k);
-	return LDNS_STATUS_ERR;
-}
-
-#ifdef HAVE_SSL
-RSA *
-ldns_key_new_frm_fp_rsa(FILE *f)
-{
-	return ldns_key_new_frm_fp_rsa_l(f, NULL);
-}
-
-RSA *
-ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
-{
-	/* we parse
- 	 * Modulus:
- 	 * PublicExponent:
- 	 * PrivateExponent:
- 	 * Prime1:
- 	 * Prime2:
- 	 * Exponent1:
- 	 * Exponent2:
- 	 * Coefficient:
-	 *
-	 * man 3 RSA:
-	 *
-	 * struct
-         *     {
-         *     BIGNUM *n;              // public modulus
-         *     BIGNUM *e;              // public exponent
-         *     BIGNUM *d;              // private exponent
-         *     BIGNUM *p;              // secret prime factor
-         *     BIGNUM *q;              // secret prime factor
-         *     BIGNUM *dmp1;           // d mod (p-1)
-         *     BIGNUM *dmq1;           // d mod (q-1)
-         *     BIGNUM *iqmp;           // q^-1 mod p
-         *     // ...
-	 *
-	 */
-	char *d;
-	RSA *rsa;
-	uint8_t *buf;
-	int i;
-
-	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
-	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
-	rsa = RSA_new();
-	if (!d || !rsa || !buf) {
-                goto error;
-	}
-
-	/* I could use functions again, but that seems an overkill,
-	 * allthough this also looks tedious
-	 */
-
-	/* Modules, rsa->n */
-	if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-#ifndef S_SPLINT_S
-	rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!rsa->n) {
-		goto error;
-	}
-
-	/* PublicExponent, rsa->e */
-	if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!rsa->e) {
-		goto error;
-	}
-
-	/* PrivateExponent, rsa->d */
-	if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!rsa->d) {
-		goto error;
-	}
-
-	/* Prime1, rsa->p */
-	if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!rsa->p) {
-		goto error;
-	}
-
-	/* Prime2, rsa->q */
-	if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!rsa->q) {
-		goto error;
-	}
-
-	/* Exponent1, rsa->dmp1 */
-	if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!rsa->dmp1) {
-		goto error;
-	}
-
-	/* Exponent2, rsa->dmq1 */
-	if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!rsa->dmq1) {
-		goto error;
-	}
-
-	/* Coefficient, rsa->iqmp */
-	if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!rsa->iqmp) {
-		goto error;
-	}
-#endif /* splint */
-
-	LDNS_FREE(buf);
-	LDNS_FREE(d);
-	return rsa;
-
-error:
-	RSA_free(rsa);
-	LDNS_FREE(d);
-	LDNS_FREE(buf);
-	return NULL;
-}
-
-DSA *
-ldns_key_new_frm_fp_dsa(FILE *f)
-{
-	return ldns_key_new_frm_fp_dsa_l(f, NULL);
-}
-
-DSA *
-ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr))
-{
-	int i;
-	char *d;
-	DSA *dsa;
-	uint8_t *buf;
-
-	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
-	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
-	dsa = DSA_new();
-	if (!d || !dsa || !buf) {
-                goto error;
-	}
-
-	/* the line parser removes the () from the input... */
-
-	/* Prime, dsa->p */
-	if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-#ifndef S_SPLINT_S
-	dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!dsa->p) {
-		goto error;
-	}
-
-	/* Subprime, dsa->q */
-	if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!dsa->q) {
-		goto error;
-	}
-
-	/* Base, dsa->g */
-	if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!dsa->g) {
-		goto error;
-	}
-
-	/* Private key, dsa->priv_key */
-	if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!dsa->priv_key) {
-		goto error;
-	}
-
-	/* Public key, dsa->priv_key */
-	if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
-	dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
-	if (!dsa->pub_key) {
-		goto error;
-	}
-#endif /* splint */
-
-	LDNS_FREE(buf);
-	LDNS_FREE(d);
-
-	return dsa;
-
-error:
-	LDNS_FREE(d);
-	LDNS_FREE(buf);
-        DSA_free(dsa);
-	return NULL;
-}
-
-unsigned char *
-ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size)
-{
-	return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size);
-}
-
-unsigned char *
-ldns_key_new_frm_fp_hmac_l( FILE *f
-			  , ATTR_UNUSED(int *line_nr)
-			  , size_t *hmac_size
-			  )
-{
-	size_t i, bufsz;
-	char d[LDNS_MAX_LINELEN];
-	unsigned char *buf = NULL;
-
-	if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
-		goto error;
-	}
-	bufsz = ldns_b64_ntop_calculate_size(strlen(d));
-	buf = LDNS_XMALLOC(unsigned char, bufsz);
-	i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz);
-
-	*hmac_size = i;
-	return buf;
-
-	error:
-	LDNS_FREE(buf);
-	*hmac_size = 0;
-	return NULL;
-}
-#endif /* HAVE_SSL */
-
-#ifdef USE_GOST
-static EVP_PKEY*
-ldns_gen_gost_key(void)
-{
-	EVP_PKEY_CTX* ctx;
-	EVP_PKEY* p = NULL;
-	int gost_id = ldns_key_EVP_load_gost_id();
-	if(!gost_id)
-		return NULL;
-	ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
-	if(!ctx) {
-		/* the id should be available now */
-		return NULL;
-	}
-	if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
-		/* cannot set paramset */
-		EVP_PKEY_CTX_free(ctx);
-		return NULL;
-	}
-
-	if(EVP_PKEY_keygen_init(ctx) <= 0) {
-		EVP_PKEY_CTX_free(ctx);
-		return NULL;
-	}
-	if(EVP_PKEY_keygen(ctx, &p) <= 0) {
-		EVP_PKEY_free(p);
-		EVP_PKEY_CTX_free(ctx);
-		return NULL;
-	}
-	EVP_PKEY_CTX_free(ctx);
-	return p;
-}
-#endif
-
-ldns_key *
-ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
-{
-	ldns_key *k;
-#ifdef HAVE_SSL
-	DSA *d;
-	RSA *r;
-#  ifdef USE_ECDSA
-        EC_KEY *ec = NULL;
-#  endif
-#else
-	int i;
-	uint16_t offset = 0;
-#endif
-	unsigned char *hmac;
-
-	k = ldns_key_new();
-	if (!k) {
-		return NULL;
-	}
-	switch(alg) {
-		case LDNS_SIGN_RSAMD5:
-		case LDNS_SIGN_RSASHA1:
-		case LDNS_SIGN_RSASHA1_NSEC3:
-		case LDNS_SIGN_RSASHA256:
-		case LDNS_SIGN_RSASHA512:
-#ifdef HAVE_SSL
-			r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
-                        if(!r) {
-				ldns_key_free(k);
-				return NULL;
-			}
-			if (RSA_check_key(r) != 1) {
-				ldns_key_free(k);
-				return NULL;
-			}
-			ldns_key_set_rsa_key(k, r);
-			RSA_free(r);
-#endif /* HAVE_SSL */
-			break;
-		case LDNS_SIGN_DSA:
-		case LDNS_SIGN_DSA_NSEC3:
-#ifdef HAVE_SSL
-			d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
-			if (!d) {
-				ldns_key_free(k);
-				return NULL;
-			}
-			if (DSA_generate_key(d) != 1) {
-				ldns_key_free(k);
-				return NULL;
-			}
-			ldns_key_set_dsa_key(k, d);
-			DSA_free(d);
-#endif /* HAVE_SSL */
-			break;
-		case LDNS_SIGN_HMACMD5:
-		case LDNS_SIGN_HMACSHA1:
-		case LDNS_SIGN_HMACSHA256:
-#ifdef HAVE_SSL
-#ifndef S_SPLINT_S
-			k->_key.key = NULL;
-#endif /* splint */
-#endif /* HAVE_SSL */
-			size = size / 8;
-			ldns_key_set_hmac_size(k, size);
-
-			hmac = LDNS_XMALLOC(unsigned char, size);
-                        if(!hmac) {
-				ldns_key_free(k);
-				return NULL;
-                        }
-#ifdef HAVE_SSL
-			if (RAND_bytes(hmac, (int) size) != 1) {
-				LDNS_FREE(hmac);
-				ldns_key_free(k);
-				return NULL;
-			}
-#else
-			while (offset + sizeof(i) < size) {
-			  i = random();
-			  memcpy(&hmac[offset], &i, sizeof(i));
-			  offset += sizeof(i);
-			}
-			if (offset < size) {
-			  i = random();
-			  memcpy(&hmac[offset], &i, size - offset);
-			}
-#endif /* HAVE_SSL */
-			ldns_key_set_hmac_key(k, hmac);
-
-			ldns_key_set_flags(k, 0);
-			break;
-		case LDNS_SIGN_ECC_GOST:
-#if defined(HAVE_SSL) && defined(USE_GOST)
-			ldns_key_set_evp_key(k, ldns_gen_gost_key());
-#ifndef S_SPLINT_S
-                        if(!k->_key.key) {
-                                ldns_key_free(k);
-                                return NULL;
-                        }
-#endif /* splint */
-#else
-			ldns_key_free(k);
-			return NULL;
-#endif /* HAVE_SSL and USE_GOST */
-                        break;
-                case LDNS_SIGN_ECDSAP256SHA256:
-                case LDNS_SIGN_ECDSAP384SHA384:
-#ifdef USE_ECDSA
-                        if(alg == LDNS_SIGN_ECDSAP256SHA256)
-                                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
-                        else if(alg == LDNS_SIGN_ECDSAP384SHA384)
-                                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
-                        if(!ec) {
-                                ldns_key_free(k);
-                                return NULL;
-                        }
-                        if(!EC_KEY_generate_key(ec)) {
-                                ldns_key_free(k);
-                                EC_KEY_free(ec);
-                                return NULL;
-                        }
-#ifndef S_SPLINT_S
-                        k->_key.key = EVP_PKEY_new();
-                        if(!k->_key.key) {
-                                ldns_key_free(k);
-                                EC_KEY_free(ec);
-                                return NULL;
-                        }
-                        if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) {
-                                ldns_key_free(k);
-                                EC_KEY_free(ec);
-                                return NULL;
-			}
-#endif /* splint */
-#else
-			ldns_key_free(k);
-			return NULL;
-#endif /* ECDSA */
-			break;
-	}
-	ldns_key_set_algorithm(k, alg);
-	return k;
-}
-
-void
-ldns_key_print(FILE *output, const ldns_key *k)
-{
-	char *str = ldns_key2str(k);
-	if (str) {
-                fprintf(output, "%s", str);
-        } else {
-                fprintf(output, "Unable to convert private key to string\n");
-        }
-        LDNS_FREE(str);
-}
-
-
-void
-ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l)
-{
-	k->_alg = l;
-}
-
-void
-ldns_key_set_flags(ldns_key *k, uint16_t f)
-{
-	k->_extra.dnssec.flags = f;
-}
-
-#ifdef HAVE_SSL
-#ifndef S_SPLINT_S
-void
-ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
-{
-	k->_key.key = e;
-}
-
-void
-ldns_key_set_rsa_key(ldns_key *k, RSA *r)
-{
-	EVP_PKEY *key = EVP_PKEY_new();
-	EVP_PKEY_set1_RSA(key, r);
-	k->_key.key = key;
-}
-
-void
-ldns_key_set_dsa_key(ldns_key *k, DSA *d)
-{
-	EVP_PKEY *key = EVP_PKEY_new();
-	EVP_PKEY_set1_DSA(key, d);
-	k->_key.key  = key;
-}
-
-void
-ldns_key_assign_rsa_key(ldns_key *k, RSA *r)
-{
-	EVP_PKEY *key = EVP_PKEY_new();
-	EVP_PKEY_assign_RSA(key, r);
-	k->_key.key = key;
-}
-
-void
-ldns_key_assign_dsa_key(ldns_key *k, DSA *d)
-{
-	EVP_PKEY *key = EVP_PKEY_new();
-	EVP_PKEY_assign_DSA(key, d);
-	k->_key.key  = key;
-}
-#endif /* splint */
-#endif /* HAVE_SSL */
-
-void
-ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
-{
-	k->_key.hmac.key = hmac;
-}
-
-void
-ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
-{
-	k->_key.hmac.size = hmac_size;
-}
-
-void
-ldns_key_set_external_key(ldns_key *k, void *external_key)
-{
-	k->_key.external_key = external_key;
-}
-
-void
-ldns_key_set_origttl(ldns_key *k, uint32_t t)
-{
-	k->_extra.dnssec.orig_ttl = t;
-}
-
-void
-ldns_key_set_inception(ldns_key *k, uint32_t i)
-{
-	k->_extra.dnssec.inception = i;
-}
-
-void
-ldns_key_set_expiration(ldns_key *k, uint32_t e)
-{
-	k->_extra.dnssec.expiration = e;
-}
-
-void
-ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
-{
-	k->_pubkey_owner = r;
-}
-
-void
-ldns_key_set_keytag(ldns_key *k, uint16_t tag)
-{
-	k->_extra.dnssec.keytag = tag;
-}
-
-/* read */
-size_t
-ldns_key_list_key_count(const ldns_key_list *key_list)
-{
-	        return key_list->_key_count;
-}       
-
-ldns_key *
-ldns_key_list_key(const ldns_key_list *key, size_t nr)
-{       
-	if (nr < ldns_key_list_key_count(key)) {
-		return key->_keys[nr];
-	} else {
-		return NULL;
-	}
-}
-
-ldns_signing_algorithm
-ldns_key_algorithm(const ldns_key *k) 
-{
-	return k->_alg;
-}
-
-void
-ldns_key_set_use(ldns_key *k, bool v)
-{
-	if (k) {
-		k->_use = v;
-	}
-}
-
-bool
-ldns_key_use(const ldns_key *k)
-{
-	if (k) {
-		return k->_use;
-	}
-	return false;
-}
-
-#ifdef HAVE_SSL
-#ifndef S_SPLINT_S
-EVP_PKEY *
-ldns_key_evp_key(const ldns_key *k)
-{
-	return k->_key.key;
-}
-
-RSA *
-ldns_key_rsa_key(const ldns_key *k)
-{
-	if (k->_key.key) {
-		return EVP_PKEY_get1_RSA(k->_key.key);
-	} else {
-		return NULL;
-	}
-}
-
-DSA *
-ldns_key_dsa_key(const ldns_key *k)
-{
-	if (k->_key.key) {
-		return EVP_PKEY_get1_DSA(k->_key.key);
-	} else {
-		return NULL;
-	}
-}
-#endif /* splint */
-#endif /* HAVE_SSL */
-
-unsigned char *
-ldns_key_hmac_key(const ldns_key *k)
-{
-	if (k->_key.hmac.key) {
-		return k->_key.hmac.key;
-	} else {
-		return NULL;
-	}
-}
-
-size_t
-ldns_key_hmac_size(const ldns_key *k)
-{
-	if (k->_key.hmac.size) {
-		return k->_key.hmac.size;
-	} else {
-		return 0;
-	}
-}
-
-void *
-ldns_key_external_key(const ldns_key *k)
-{
-	return k->_key.external_key;
-}
-
-uint32_t
-ldns_key_origttl(const ldns_key *k)
-{
-	return k->_extra.dnssec.orig_ttl;
-}
-
-uint16_t
-ldns_key_flags(const ldns_key *k)
-{
-	return k->_extra.dnssec.flags;
-}
-
-uint32_t
-ldns_key_inception(const ldns_key *k)
-{
-	return k->_extra.dnssec.inception;
-}
-
-uint32_t
-ldns_key_expiration(const ldns_key *k)
-{
-	return k->_extra.dnssec.expiration;
-}
-
-uint16_t
-ldns_key_keytag(const ldns_key *k)
-{
-	return k->_extra.dnssec.keytag;
-}
-
-ldns_rdf *
-ldns_key_pubkey_owner(const ldns_key *k)
-{
-	return k->_pubkey_owner;
-}
-
-/* write */
-void
-ldns_key_list_set_use(ldns_key_list *keys, bool v)
-{
-	size_t i;
-
-	for (i = 0; i < ldns_key_list_key_count(keys); i++) {
-		ldns_key_set_use(ldns_key_list_key(keys, i), v);
-	}
-}
-
-void            
-ldns_key_list_set_key_count(ldns_key_list *key, size_t count)
-{
-	        key->_key_count = count;
-}       
-
-bool             
-ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
-{       
-        size_t key_count;
-        ldns_key **keys;
-
-        key_count = ldns_key_list_key_count(key_list);
-
-        /* grow the array */
-        keys = LDNS_XREALLOC(
-                key_list->_keys, ldns_key *, key_count + 1);
-        if (!keys) {
-                return false;
-        }
-
-        /* add the new member */
-        key_list->_keys = keys;
-        key_list->_keys[key_count] = key;
-
-        ldns_key_list_set_key_count(key_list, key_count + 1);
-        return true;
-}
-
-ldns_key *
-ldns_key_list_pop_key(ldns_key_list *key_list)
-{                               
-        size_t key_count;
-        ldns_key** a;
-        ldns_key *pop;
-
-	if (!key_list) {
-		return NULL;
-	}
-        
-        key_count = ldns_key_list_key_count(key_list);
-        if (key_count == 0) {
-                return NULL;
-        }       
-        
-        pop = ldns_key_list_key(key_list, key_count);
-        
-        /* shrink the array */
-        a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1);
-        if(a) {
-                key_list->_keys = a;
-        }
-
-        ldns_key_list_set_key_count(key_list, key_count - 1);
-
-        return pop;
-}       
-
-#ifdef HAVE_SSL
-#ifndef S_SPLINT_S
-/* data pointer must be large enough (LDNS_MAX_KEYLEN) */
-static bool
-ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
-{
-	int i,j;
-	
-	if (!k) {
-		return false;
-	}
-	
-	if (BN_num_bytes(k->e) <= 256) {
-		/* normally only this path is executed (small factors are
-		 * more common 
-		 */
-		data[0] = (unsigned char) BN_num_bytes(k->e);
-		i = BN_bn2bin(k->e, data + 1);  
-		j = BN_bn2bin(k->n, data + i + 1);
-		*size = (uint16_t) i + j;
-	} else if (BN_num_bytes(k->e) <= 65536) {
-		data[0] = 0;
-		/* BN_bn2bin does bigendian, _uint16 also */
-		ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 
-
-		BN_bn2bin(k->e, data + 3); 
-		BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e));
-		*size = (uint16_t) BN_num_bytes(k->n) + 6;
-	} else {
-		return false;
-	}
-	return true;
-}
-
-/* data pointer must be large enough (LDNS_MAX_KEYLEN) */
-static bool
-ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
-{
-	uint8_t T;
-
-	if (!k) {
-		return false;
-	}
-	
-	/* See RFC2536 */
-	*size = (uint16_t)BN_num_bytes(k->p);
-	T = (*size - 64) / 8;
-
-	if (T > 8) {
-#ifdef STDERR_MSGS
-		fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
-		fprintf(stderr, " not implemented\n");
-#endif
-		return false;
-	}
-
-	/* size = 64 + (T * 8); */
-	memset(data, 0, 21 + *size * 3);
-	data[0] = (unsigned char)T;
-	BN_bn2bin(k->q, data + 1 ); 		/* 20 octects */
-	BN_bn2bin(k->p, data + 21 ); 		/* offset octects */
-	BN_bn2bin(k->g, data + 21 + *size * 2 - BN_num_bytes(k->g));
-	BN_bn2bin(k->pub_key,data + 21 + *size * 3 - BN_num_bytes(k->pub_key));
-	*size = 21 + *size * 3;
-	return true;
-}
-
-#ifdef USE_GOST
-static bool
-ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
-{
-	int i;
-	unsigned char* pp = NULL;
-	if(i2d_PUBKEY(k, &pp) != 37 + 64) {
-		/* expect 37 byte(ASN header) and 64 byte(X and Y) */
-		CRYPTO_free(pp);
-		return false;
-	}
-	/* omit ASN header */
-	for(i=0; i<64; i++)
-		data[i] = pp[i+37];
-	CRYPTO_free(pp);
-	*size = 64;
-	return true;
-}
-#endif /* USE_GOST */
-#endif /* splint */
-#endif /* HAVE_SSL */
-
-ldns_rr *
-ldns_key2rr(const ldns_key *k)
-{
-	/* this function will convert a the keydata contained in
-	 * rsa/dsa pointers to a DNSKEY rr. It will fill in as
-	 * much as it can, but it does not know about key-flags
-	 * for instance
-	 */
-	ldns_rr *pubkey;
-	ldns_rdf *keybin;
-	unsigned char *bin = NULL;
-	uint16_t size = 0;
-#ifdef HAVE_SSL
-	RSA *rsa = NULL;
-	DSA *dsa = NULL;
-#endif /* HAVE_SSL */
-#ifdef USE_ECDSA
-        EC_KEY* ec;
-#endif
-	int internal_data = 0;
-
-	if (!k) {
-		return NULL;
-	}
-	pubkey = ldns_rr_new();
-
-	switch (ldns_key_algorithm(k)) {
-	case LDNS_SIGN_HMACMD5:
-	case LDNS_SIGN_HMACSHA1:
-	case LDNS_SIGN_HMACSHA256:
-		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY);
-        	break;
-	default:
-		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY);
-		break;
-        }
-	/* zero-th rdf - flags */
-	ldns_rr_push_rdf(pubkey,
-			ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
-				ldns_key_flags(k)));
-	/* first - proto */
-	ldns_rr_push_rdf(pubkey,
-			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO));
-
-	if (ldns_key_pubkey_owner(k)) {
-		ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k)));
-	}
-
-	/* third - da algorithm */
-	switch(ldns_key_algorithm(k)) {
-		case LDNS_SIGN_RSAMD5:
-		case LDNS_SIGN_RSASHA1:
-		case LDNS_SIGN_RSASHA1_NSEC3:
-		case LDNS_SIGN_RSASHA256:
-		case LDNS_SIGN_RSASHA512:
-			ldns_rr_push_rdf(pubkey,
-						  ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
-#ifdef HAVE_SSL
-			rsa =  ldns_key_rsa_key(k);
-			if (rsa) {
-				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
-				if (!bin) {
-                                        ldns_rr_free(pubkey);
-					return NULL;
-				}
-				if (!ldns_key_rsa2bin(bin, rsa, &size)) {
-		                        LDNS_FREE(bin);
-                                        ldns_rr_free(pubkey);
-					return NULL;
-				}
-				RSA_free(rsa);
-				internal_data = 1;
-			}
-#endif
-			size++;
-			break;
-		case LDNS_SIGN_DSA:
-			ldns_rr_push_rdf(pubkey,
-					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
-#ifdef HAVE_SSL
-			dsa = ldns_key_dsa_key(k);
-			if (dsa) {
-				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
-				if (!bin) {
-                                        ldns_rr_free(pubkey);
-					return NULL;
-				}
-				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
-		                        LDNS_FREE(bin);
-                                        ldns_rr_free(pubkey);
-					return NULL;
-				}
-				DSA_free(dsa);
-				internal_data = 1;
-			}
-#endif /* HAVE_SSL */
-			break;
-		case LDNS_SIGN_DSA_NSEC3:
-			ldns_rr_push_rdf(pubkey,
-					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3));
-#ifdef HAVE_SSL
-			dsa = ldns_key_dsa_key(k);
-			if (dsa) {
-				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
-				if (!bin) {
-                                        ldns_rr_free(pubkey);
-					return NULL;
-				}
-				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
-		                        LDNS_FREE(bin);
-                                        ldns_rr_free(pubkey);
-					return NULL;
-				}
-				DSA_free(dsa);
-				internal_data = 1;
-			}
-#endif /* HAVE_SSL */
-			break;
-		case LDNS_SIGN_ECC_GOST:
-			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
-				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
-#if defined(HAVE_SSL) && defined(USE_GOST)
-			bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
-			if (!bin) {
-                                ldns_rr_free(pubkey);
-				return NULL;
-                        }
-#ifndef S_SPLINT_S
-			if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
-		                LDNS_FREE(bin);
-                                ldns_rr_free(pubkey);
-				return NULL;
-			}
-#endif /* splint */
-			internal_data = 1;
-#else
-                        ldns_rr_free(pubkey);
-			return NULL;
-#endif /* HAVE_SSL and USE_GOST */
-			break;
-                case LDNS_SIGN_ECDSAP256SHA256:
-                case LDNS_SIGN_ECDSAP384SHA384:
-#ifdef USE_ECDSA
-			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
-				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
-                        bin = NULL;
-#ifndef S_SPLINT_S
-                        ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
-#endif
-                        EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
-                        size = (uint16_t)i2o_ECPublicKey(ec, NULL);
-                        if(!i2o_ECPublicKey(ec, &bin)) {
-                                EC_KEY_free(ec);
-                                ldns_rr_free(pubkey);
-                                return NULL;
-                        }
-			if(size > 1) {
-				/* move back one byte to shave off the 0x02
-				 * 'uncompressed' indicator that openssl made
-				 * Actually its 0x04 (from implementation).
-				 */
-				assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
-				size -= 1;
-				memmove(bin, bin+1, size);
-			}
-                        /* down the reference count for ec, its still assigned
-                         * to the pkey */
-                        EC_KEY_free(ec);
-			internal_data = 1;
-#else
-                        ldns_rr_free(pubkey);
-			return NULL;
-#endif /* ECDSA */
-                        break;
-		case LDNS_SIGN_HMACMD5:
-		case LDNS_SIGN_HMACSHA1:
-		case LDNS_SIGN_HMACSHA256:
-			bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
-			if (!bin) {
-                                ldns_rr_free(pubkey);
-				return NULL;
-			}
-			ldns_rr_push_rdf(pubkey,
-			                 ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
-			                 ldns_key_algorithm(k)));
-			size = ldns_key_hmac_size(k);
-			memcpy(bin, ldns_key_hmac_key(k), size);
-			internal_data = 1;
-			break;
-	}
-	/* fourth the key bin material */
-	if (internal_data) {
-		keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin);
-		LDNS_FREE(bin);
-		ldns_rr_push_rdf(pubkey, keybin);
-	}
-	return pubkey;
-}
-
-void
-ldns_key_free(ldns_key *key)
-{
-	LDNS_FREE(key);
-}
-
-void
-ldns_key_deep_free(ldns_key *key)
-{
-	unsigned char* hmac;
-	if (ldns_key_pubkey_owner(key)) {
-		ldns_rdf_deep_free(ldns_key_pubkey_owner(key));
-	}
-#ifdef HAVE_SSL
-	if (ldns_key_evp_key(key)) {
-		EVP_PKEY_free(ldns_key_evp_key(key));
-	}
-#endif /* HAVE_SSL */
-	if (ldns_key_hmac_key(key)) {
-		hmac = ldns_key_hmac_key(key);
-		LDNS_FREE(hmac);
-	}
-	LDNS_FREE(key);
-}
-
-void
-ldns_key_list_free(ldns_key_list *key_list)
-{
-	size_t i;
-	for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
-		ldns_key_deep_free(ldns_key_list_key(key_list, i));
-	}
-	LDNS_FREE(key_list->_keys);
-	LDNS_FREE(key_list);
-}
-
-ldns_rr *
-ldns_read_anchor_file(const char *filename)
-{
-	FILE *fp;
-	/*char line[LDNS_MAX_PACKETLEN];*/
-	char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN);
-	int c;
-	size_t i = 0;
-	ldns_rr *r;
-	ldns_status status;
-        if(!line) {
-                return NULL;
-        }
-
-	fp = fopen(filename, "r");
-	if (!fp) {
-#ifdef STDERR_MSGS
-		fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
-#endif
-		LDNS_FREE(line);
-		return NULL;
-	}
-	
-	while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) {
-		line[i] = c;
-		i++;
-	}
-	line[i] = '\0';
-	
-	fclose(fp);
-	
-	if (i <= 0) {
-#ifdef STDERR_MSGS
-		fprintf(stderr, "nothing read from %s", filename);
-#endif
-		LDNS_FREE(line);
-		return NULL;
-	} else {
-		status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
-		if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) {
-			LDNS_FREE(line);
-			return r;
-		} else {
-#ifdef STDERR_MSGS
-			fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
-#endif
-			LDNS_FREE(line);
-			return NULL;
-		}
-	}
-}
-
-char *
-ldns_key_get_file_base_name(ldns_key *key)
-{
-	ldns_buffer *buffer;
-	char *file_base_name;
-	
-	buffer = ldns_buffer_new(255);
-	ldns_buffer_printf(buffer, "K");
-	(void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key));
-	ldns_buffer_printf(buffer,
-	                   "+%03u+%05u",
-			   ldns_key_algorithm(key),
-			   ldns_key_keytag(key));
-	file_base_name = ldns_buffer_export(buffer);
-	ldns_buffer_free(buffer);
-	return file_base_name;
-}
-
-int ldns_key_algo_supported(int algo)
-{
-	ldns_lookup_table *lt = ldns_signing_algorithms;
-	while(lt->name) {
-		if(lt->id == algo)
-			return 1;
-		lt++;
-	}
-	return 0;
-}
-
-ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name)
-{
-        /* list of (signing algorithm id, alias_name) */
-        ldns_lookup_table aliases[] = {
-                /* from bind dnssec-keygen */
-                {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
-                {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
-                {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
-                /* old ldns usage, now RFC names */
-                {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
-                {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
-#ifdef USE_GOST
-                {LDNS_SIGN_ECC_GOST, "GOST"},
-#endif
-                /* compat with possible output */
-                {LDNS_DH, "DH"},
-                {LDNS_ECC, "ECC"},
-                {LDNS_INDIRECT, "INDIRECT"},
-                {LDNS_PRIVATEDNS, "PRIVATEDNS"},
-                {LDNS_PRIVATEOID, "PRIVATEOID"},
-                {0, NULL}};
-        ldns_lookup_table* lt = ldns_signing_algorithms;
-	ldns_signing_algorithm a;
-	char *endptr;
-
-        while(lt->name) {
-                if(strcasecmp(lt->name, name) == 0)
-                        return lt->id;
-                lt++;
-        }
-        lt = aliases;
-        while(lt->name) {
-                if(strcasecmp(lt->name, name) == 0)
-                        return lt->id;
-                lt++;
-        }
-	a = strtol(name, &endptr, 10);
-	if (*name && !*endptr)
-		return a;
-
-        return 0;
-}
diff --git a/src/ldns/net.c b/src/ldns/net.c
deleted file mode 100644
index b8a5385..0000000
--- a/src/ldns/net.c
+++ /dev/null
@@ -1,1002 +0,0 @@
-/*
- * net.c
- *
- * Network implementation
- * All network related functions are grouped here
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#include <sys/time.h>
-#include <errno.h>
-#include <fcntl.h>
-
-ldns_status
-ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
-{
-	ldns_buffer *qb;
-	ldns_status result;
-	ldns_rdf *tsig_mac = NULL;
-
-	qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
-
-	if (query_pkt && ldns_pkt_tsig(query_pkt)) {
-		tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
-	}
-
-	if (!query_pkt ||
-	    ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
-		result = LDNS_STATUS_ERR;
-	} else {
-        	result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
-	}
-
-	ldns_buffer_free(qb);
-
-	return result;
-}
-
-/* code from rdata.c */
-static struct sockaddr_storage *
-ldns_rdf2native_sockaddr_storage_port(
-		const ldns_rdf *rd, uint16_t port, size_t *size)
-{
-        struct sockaddr_storage *data;
-        struct sockaddr_in  *data_in;
-        struct sockaddr_in6 *data_in6;
-
-        data = LDNS_MALLOC(struct sockaddr_storage);
-        if (!data) {
-                return NULL;
-        }
-	/* zero the structure for portability */
-	memset(data, 0, sizeof(struct sockaddr_storage));
-
-        switch(ldns_rdf_get_type(rd)) {
-                case LDNS_RDF_TYPE_A:
-#ifndef S_SPLINT_S
-                        data->ss_family = AF_INET;
-#endif
-                        data_in = (struct sockaddr_in*) data;
-                        data_in->sin_port = (in_port_t)htons(port);
-                        memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
-                        *size = sizeof(struct sockaddr_in);
-                        return data;
-                case LDNS_RDF_TYPE_AAAA:
-#ifndef S_SPLINT_S
-                        data->ss_family = AF_INET6;
-#endif
-                        data_in6 = (struct sockaddr_in6*) data;
-                        data_in6->sin6_port = (in_port_t)htons(port);
-                        memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
-                        *size = sizeof(struct sockaddr_in6);
-                        return data;
-                default:
-                        LDNS_FREE(data);
-                        return NULL;
-        }
-}
-
-struct sockaddr_storage *
-ldns_rdf2native_sockaddr_storage(
-		const ldns_rdf *rd, uint16_t port, size_t *size)
-{
-	return ldns_rdf2native_sockaddr_storage_port(
-			rd, (port == 0 ? (uint16_t)LDNS_PORT : port), size);
-}
-
-/** best effort to set nonblocking */
-static void
-ldns_sock_nonblock(int sockfd)
-{
-#ifdef HAVE_FCNTL
-	int flag;
-	if((flag = fcntl(sockfd, F_GETFL)) != -1) {
-		flag |= O_NONBLOCK;
-		if(fcntl(sockfd, F_SETFL, flag) == -1) {
-			/* ignore error, continue blockingly */
-		}
-	}
-#elif defined(HAVE_IOCTLSOCKET)
-	unsigned long on = 1;
-	if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
-		/* ignore error, continue blockingly */
-	}
-#endif
-}
-
-/** best effort to set blocking */
-static void
-ldns_sock_block(int sockfd)
-{
-#ifdef HAVE_FCNTL
-	int flag;
-	if((flag = fcntl(sockfd, F_GETFL)) != -1) {
-		flag &= ~O_NONBLOCK;
-		if(fcntl(sockfd, F_SETFL, flag) == -1) {
-			/* ignore error, continue */
-		}
-	}
-#elif defined(HAVE_IOCTLSOCKET)
-	unsigned long off = 0;
-	if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
-		/* ignore error, continue */
-	}
-#endif
-}
-
-/** wait for a socket to become ready */
-static int
-ldns_sock_wait(int sockfd, struct timeval timeout, int write)
-{
-	int ret;
-#ifndef S_SPLINT_S
-	fd_set fds;
-	FD_ZERO(&fds);
-	FD_SET(FD_SET_T sockfd, &fds);
-	if(write)
-		ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
-	else
-		ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
-#endif
-	if(ret == 0)
-		/* timeout expired */
-		return 0;
-	else if(ret == -1)
-		/* error */
-		return 0;
-	return 1;
-}
-
-
-static int
-ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen, 
-	       	const struct sockaddr_storage *from, socklen_t fromlen,
-		struct timeval timeout)
-{
-	int sockfd;
-
-#ifndef S_SPLINT_S
-	if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM, 
-					IPPROTO_TCP)) == -1) {
-		return 0;
-	}
-#endif
-	if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
-		return 0;
-	}
-
-	/* perform nonblocking connect, to be able to wait with select() */
-	ldns_sock_nonblock(sockfd);
-	if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) {
-#ifndef USE_WINSOCK
-#ifdef EINPROGRESS
-		if(errno != EINPROGRESS) {
-#else
-		if(1) {
-#endif
-			close(sockfd);
-			return 0;
-		}
-#else /* USE_WINSOCK */
-		if(WSAGetLastError() != WSAEINPROGRESS &&
-			WSAGetLastError() != WSAEWOULDBLOCK) {
-			closesocket(sockfd);
-			return 0;
-		}
-#endif
-		/* error was only telling us that it would block */
-	}
-
-	/* wait(write) until connected or error */
-	while(1) {
-		int error = 0;
-		socklen_t len = (socklen_t)sizeof(error);
-
-		if(!ldns_sock_wait(sockfd, timeout, 1)) {
-#ifndef USE_WINSOCK
-			close(sockfd);
-#else
-			closesocket(sockfd);
-#endif
-			return 0;
-		}
-
-		/* check if there is a pending error for nonblocking connect */
-		if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error,
-			&len) < 0) {
-#ifndef USE_WINSOCK
-			error = errno; /* on solaris errno is error */
-#else
-			error = WSAGetLastError();
-#endif
-		}
-#ifndef USE_WINSOCK
-#if defined(EINPROGRESS) && defined(EWOULDBLOCK)
-		if(error == EINPROGRESS || error == EWOULDBLOCK)
-			continue; /* try again */
-#endif
-		else if(error != 0) {
-			close(sockfd);
-			/* error in errno for our user */
-			errno = error;
-			return 0;
-		}
-#else /* USE_WINSOCK */
-		if(error == WSAEINPROGRESS)
-			continue;
-		else if(error == WSAEWOULDBLOCK)
-			continue;
-		else if(error != 0) {
-			closesocket(sockfd);
-			errno = error;
-			return 0;
-		}
-#endif /* USE_WINSOCK */
-		/* connected */
-		break;
-	}
-
-	/* set the socket blocking again */
-	ldns_sock_block(sockfd);
-
-	return sockfd;
-}
-
-int
-ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, 
-		struct timeval timeout)
-{
-	return ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
-}
-
-static int
-ldns_tcp_bgsend_from(ldns_buffer *qbin,
-		const struct sockaddr_storage *to, socklen_t tolen, 
-	       	const struct sockaddr_storage *from, socklen_t fromlen,
-		struct timeval timeout)
-{
-	int sockfd;
-	
-	sockfd = ldns_tcp_connect_from(to, tolen, from, fromlen, timeout);
-	
-	if (sockfd == 0) {
-		return 0;
-	}
-	
-	if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
-#ifndef USE_WINSOCK
-		close(sockfd);
-#else
-		closesocket(sockfd);
-#endif
-		return 0;
-	}
-	
-	return sockfd;
-}
-
-int
-ldns_tcp_bgsend(ldns_buffer *qbin,
-		const struct sockaddr_storage *to, socklen_t tolen, 
-		struct timeval timeout)
-{
-	return ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
-}
-
-
-/* keep in mind that in DNS tcp messages the first 2 bytes signal the
- * amount data to expect
- */
-static ldns_status
-ldns_tcp_send_from(uint8_t **result,  ldns_buffer *qbin,
-	       	const struct sockaddr_storage *to, socklen_t tolen,
-	       	const struct sockaddr_storage *from, socklen_t fromlen,
-		struct timeval timeout, size_t *answer_size)
-{
-	int sockfd;
-	uint8_t *answer;
-	
-	sockfd = ldns_tcp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
-	
-	if (sockfd == 0) {
-		return LDNS_STATUS_ERR;
-	}
-
-	answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
-#ifndef USE_WINSOCK
-	close(sockfd);
-#else
-	closesocket(sockfd);
-#endif
-
-	if (*answer_size == 0) {
-		/* oops */
-		return LDNS_STATUS_NETWORK_ERR;
-	}
-
-	/* resize accordingly */
-	*result = LDNS_XREALLOC(answer, uint8_t, (size_t)*answer_size);
-        if(!*result) {
-                LDNS_FREE(answer);
-                return LDNS_STATUS_MEM_ERR;
-        }
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_tcp_send(uint8_t **result,  ldns_buffer *qbin,
-		const struct sockaddr_storage *to, socklen_t tolen,
-		struct timeval timeout, size_t *answer_size)
-{
-	return ldns_tcp_send_from(result, qbin,
-			to, tolen, NULL, 0, timeout, answer_size);
-}
-
-int
-ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
-{
-	int sockfd;
-
-#ifndef S_SPLINT_S
-	if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM, 
-					IPPROTO_UDP)) 
-			== -1) {
-                return 0;
-        }
-#endif
-	return sockfd;
-}
-
-static int
-ldns_udp_bgsend_from(ldns_buffer *qbin,
-		const struct sockaddr_storage *to  , socklen_t tolen, 
-		const struct sockaddr_storage *from, socklen_t fromlen, 
-		struct timeval timeout)
-{
-	int sockfd;
-
-	sockfd = ldns_udp_connect(to, timeout);
-
-	if (sockfd == 0) {
-		return 0;
-	}
-
-	if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
-		return 0;
-	}
-
-	if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
-#ifndef USE_WINSOCK
-		close(sockfd);
-#else
-		closesocket(sockfd);
-#endif
-		return 0;
-	}
-	return sockfd;
-}
-
-int
-ldns_udp_bgsend(ldns_buffer *qbin,
-		const struct sockaddr_storage *to  , socklen_t tolen, 
-		struct timeval timeout)
-{
-	return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
-}
-
-static ldns_status
-ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
-		const struct sockaddr_storage *to  , socklen_t tolen,
-		const struct sockaddr_storage *from, socklen_t fromlen,
-		struct timeval timeout, size_t *answer_size)
-{
-	int sockfd;
-	uint8_t *answer;
-
-	sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
-
-	if (sockfd == 0) {
-		return LDNS_STATUS_SOCKET_ERROR;
-	}
-
-	/* wait for an response*/
-	if(!ldns_sock_wait(sockfd, timeout, 0)) {
-#ifndef USE_WINSOCK
-		close(sockfd);
-#else
-                closesocket(sockfd);
-#endif
-		return LDNS_STATUS_NETWORK_ERR;
-	}
-
-        /* set to nonblocking, so if the checksum is bad, it becomes
-         * an EGAIN error and the ldns_udp_send function does not block,
-         * but returns a 'NETWORK_ERROR' much like a timeout. */
-        ldns_sock_nonblock(sockfd);
-
-	answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
-#ifndef USE_WINSOCK
-	close(sockfd);
-#else
-        closesocket(sockfd);
-#endif
-
-	if (*answer_size == 0) {
-		/* oops */
-		return LDNS_STATUS_NETWORK_ERR;
-	}
-
-	*result = answer;
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_udp_send(uint8_t **result, ldns_buffer *qbin,
-		const struct sockaddr_storage *to  , socklen_t tolen,
-		struct timeval timeout, size_t *answer_size)
-{
-	return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
-			timeout, answer_size);
-}
-
-ldns_status
-ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
-{
-	uint8_t i;
-
-	struct sockaddr_storage *src = NULL;
-	size_t src_len;
-	struct sockaddr_storage *ns;
-	size_t ns_len;
-	struct timeval tv_s;
-	struct timeval tv_e;
-
-	ldns_rdf **ns_array;
-	size_t *rtt;
-	ldns_pkt *reply;
-	bool all_servers_rtt_inf;
-	uint8_t retries;
-
-	uint8_t *reply_bytes = NULL;
-	size_t reply_size = 0;
-	ldns_status status, send_status;
-
-	assert(r != NULL);
-
-	status = LDNS_STATUS_OK;
-	rtt = ldns_resolver_rtt(r);
-	ns_array = ldns_resolver_nameservers(r);
-	reply = NULL; 
-	ns_len = 0;
-
-	all_servers_rtt_inf = true;
-
-	if (ldns_resolver_random(r)) {
-		ldns_resolver_nameservers_randomize(r);
-	}
-
-	if(ldns_resolver_source(r)) {
-		src = ldns_rdf2native_sockaddr_storage_port(
-				ldns_resolver_source(r), 0, &src_len);
-	}
-
-	/* loop through all defined nameservers */
-	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
-		if (rtt[i] == LDNS_RESOLV_RTT_INF) {
-			/* not reachable nameserver! */
-			continue;
-		}
-
-		/* maybe verbosity setting?
-		printf("Sending to ");
-		ldns_rdf_print(stdout, ns_array[i]);
-		printf("\n");
-		*/
-		ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
-				ldns_resolver_port(r), &ns_len);
-
-
-#ifndef S_SPLINT_S
-		if ((ns->ss_family == AF_INET) &&
-				(ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
-			/* not reachable */
-			LDNS_FREE(ns);
-			continue;
-		}
-
-		if ((ns->ss_family == AF_INET6) &&
-				 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
-			/* not reachable */
-			LDNS_FREE(ns);
-			continue;
-		}
-#endif
-
-		all_servers_rtt_inf = false;
-
-		gettimeofday(&tv_s, NULL);
-
-		send_status = LDNS_STATUS_ERR;
-
-		/* reply_bytes implicitly handles our error */
-		if (ldns_resolver_usevc(r)) {
-			for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
-				send_status = 
-					ldns_tcp_send_from(&reply_bytes, qb, 
-						ns, (socklen_t)ns_len,
-						src, (socklen_t)src_len,
-						ldns_resolver_timeout(r),
-						&reply_size);
-				if (send_status == LDNS_STATUS_OK) {
-					break;
-				}
-			}
-		} else {
-			for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
-				/* ldns_rdf_print(stdout, ns_array[i]); */
-				send_status = 
-					ldns_udp_send_from(&reply_bytes, qb,
-						ns,  (socklen_t)ns_len,
-						src, (socklen_t)src_len,
-						ldns_resolver_timeout(r),
-						&reply_size);
-				if (send_status == LDNS_STATUS_OK) {
-					break;
-				}
-			}
-		}
-
-		if (send_status != LDNS_STATUS_OK) {
-			ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
-			status = send_status;
-		}
-		
-		/* obey the fail directive */
-		if (!reply_bytes) {
-			/* the current nameserver seems to have a problem, blacklist it */
-			if (ldns_resolver_fail(r)) {
-				LDNS_FREE(ns);
-				return LDNS_STATUS_ERR;
-			} else {
-				LDNS_FREE(ns);
-				continue;
-			}
-		} 
-		
-		status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
-		if (status != LDNS_STATUS_OK) {
-			LDNS_FREE(reply_bytes);
-			LDNS_FREE(ns);
-			return status;
-		}
-		
-		LDNS_FREE(ns);
-		gettimeofday(&tv_e, NULL);
-
-		if (reply) {
-			ldns_pkt_set_querytime(reply, (uint32_t)
-				((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
-				(tv_e.tv_usec - tv_s.tv_usec) / 1000);
-			ldns_pkt_set_answerfrom(reply,
-					ldns_rdf_clone(ns_array[i]));
-			ldns_pkt_set_timestamp(reply, tv_s);
-			ldns_pkt_set_size(reply, reply_size);
-			break;
-		} else {
-			if (ldns_resolver_fail(r)) {
-				/* if fail is set bail out, after the first
-				 * one */
-				break;
-			}
-		}
-
-		/* wait retrans seconds... */
-		sleep((unsigned int) ldns_resolver_retrans(r));
-	}
-
-	if(src) {
-		LDNS_FREE(src);
-	}
-	if (all_servers_rtt_inf) {
-		LDNS_FREE(reply_bytes);
-		return LDNS_STATUS_RES_NO_NS;
-	}
-#ifdef HAVE_SSL
-	if (tsig_mac && reply && reply_bytes) {
-		if (!ldns_pkt_tsig_verify(reply,
-		                          reply_bytes,
-					  reply_size,
-		                          ldns_resolver_tsig_keyname(r),
-		                          ldns_resolver_tsig_keydata(r), tsig_mac)) {
-			status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
-		}
-	}
-#else
-	(void)tsig_mac;
-#endif /* HAVE_SSL */
-
-	LDNS_FREE(reply_bytes);
-	if (result) {
-		*result = reply;
-	}
-
-	return status;
-}
-
-ssize_t
-ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, 
-                    const struct sockaddr_storage *to, socklen_t tolen)
-{
-	uint8_t *sendbuf;
-	ssize_t bytes;
-
-	/* add length of packet */
-	sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
-	if(!sendbuf) return 0;
-	ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
-	memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
-
-	bytes = sendto(sockfd, (void*)sendbuf,
-			ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
-
-        LDNS_FREE(sendbuf);
-
-	if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
-		return 0;
-	}
-	return bytes;
-}
-
-/* don't wait for an answer */
-ssize_t
-ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, 
-		socklen_t tolen)
-{
-	ssize_t bytes;
-
-	bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
-			ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
-
-	if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
-		return 0;
-	}
-	if ((size_t) bytes != ldns_buffer_position(qbin)) {
-		return 0;
-	}
-	return bytes;
-}
-
-uint8_t *
-ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
-		socklen_t *fromlen)
-{
-	uint8_t *wire, *wireout;
-	ssize_t wire_size;
-
-	wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
-	if (!wire) {
-		*size = 0;
-		return NULL;
-	}
-
-	wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0, 
-			(struct sockaddr *)from, fromlen);
-
-	/* recvfrom can also return 0 */
-	if (wire_size == -1 || wire_size == 0) {
-		*size = 0;
-		LDNS_FREE(wire);
-		return NULL;
-	}
-
-	*size = (size_t)wire_size;
-	wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
-	if(!wireout) LDNS_FREE(wire);
-
-	return wireout;
-}
-
-uint8_t *
-ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
-{
-	uint8_t *wire;
-	uint16_t wire_size;
-	ssize_t bytes = 0, rc = 0;
-
-	wire = LDNS_XMALLOC(uint8_t, 2);
-	if (!wire) {
-		*size = 0;
-		return NULL;
-	}
-	
-	while (bytes < 2) {
-		if(!ldns_sock_wait(sockfd, timeout, 0)) {
-			*size = 0;
-			LDNS_FREE(wire);
-			return NULL;
-		}
-		rc = recv(sockfd, (void*) (wire + bytes), 
-				(size_t) (2 - bytes), 0);
-		if (rc == -1 || rc == 0) {
-			*size = 0;
-			LDNS_FREE(wire);
-			return NULL;
-		}
-                bytes += rc;
-	}
-
-	wire_size = ldns_read_uint16(wire);
-	
-	LDNS_FREE(wire);
-	wire = LDNS_XMALLOC(uint8_t, wire_size);
-	if (!wire) {
-		*size = 0;
-		return NULL;
-	}
-	bytes = 0;
-
-	while (bytes < (ssize_t) wire_size) {
-		if(!ldns_sock_wait(sockfd, timeout, 0)) {
-			*size = 0;
-			LDNS_FREE(wire);
-			return NULL;
-		}
-		rc = recv(sockfd, (void*) (wire + bytes), 
-				(size_t) (wire_size - bytes), 0);
-		if (rc == -1 || rc == 0) {
-			LDNS_FREE(wire);
-			*size = 0;
-			return NULL;
-		}
-                bytes += rc;
-	}
-	
-	*size = (size_t) bytes;
-	return wire;
-}
-
-uint8_t *
-ldns_tcp_read_wire(int sockfd, size_t *size)
-{
-	uint8_t *wire;
-	uint16_t wire_size;
-	ssize_t bytes = 0, rc = 0;
-
-	wire = LDNS_XMALLOC(uint8_t, 2);
-	if (!wire) {
-		*size = 0;
-		return NULL;
-	}
-	
-	while (bytes < 2) {
-		rc = recv(sockfd, (void*) (wire + bytes), 
-				(size_t) (2 - bytes), 0);
-		if (rc == -1 || rc == 0) {
-			*size = 0;
-			LDNS_FREE(wire);
-			return NULL;
-		}
-                bytes += rc;
-	}
-
-	wire_size = ldns_read_uint16(wire);
-	
-	LDNS_FREE(wire);
-	wire = LDNS_XMALLOC(uint8_t, wire_size);
-	if (!wire) {
-		*size = 0;
-		return NULL;
-	}
-	bytes = 0;
-
-	while (bytes < (ssize_t) wire_size) {
-		rc = recv(sockfd, (void*) (wire + bytes), 
-				(size_t) (wire_size - bytes), 0);
-		if (rc == -1 || rc == 0) {
-			LDNS_FREE(wire);
-			*size = 0;
-			return NULL;
-		}
-                bytes += rc;
-	}
-	
-	*size = (size_t) bytes;
-	return wire;
-}
-
-#ifndef S_SPLINT_S
-ldns_rdf *
-ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
-{
-        ldns_rdf *addr;
-        struct sockaddr_in *data_in;
-        struct sockaddr_in6 *data_in6;
-
-        switch(sock->ss_family) {
-                case AF_INET:
-                        data_in = (struct sockaddr_in*)sock;
-                        if (port) {
-                                *port = ntohs((uint16_t)data_in->sin_port);
-                        }
-                        addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
-                                        LDNS_IP4ADDRLEN, &data_in->sin_addr);
-                        break;
-                case AF_INET6:
-                        data_in6 = (struct sockaddr_in6*)sock;
-                        if (port) {
-                                *port = ntohs((uint16_t)data_in6->sin6_port);
-                        }
-                        addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
-                                        LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
-                        break;
-                default:
-                        if (port) {
-                                *port = 0;
-                        }
-                        return NULL;
-        }
-        return addr;
-}
-#endif
-
-/* code from resolver.c */
-ldns_status
-ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) 
-{
-        ldns_pkt *query;
-        ldns_buffer *query_wire;
-
-        struct sockaddr_storage *src = NULL;
-        size_t src_len = 0;
-        struct sockaddr_storage *ns = NULL;
-        size_t ns_len = 0;
-        size_t ns_i;
-        ldns_status status;
-
-        if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
-                return LDNS_STATUS_ERR;
-        }
-
-        query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
-
-        if (!query) {
-                return LDNS_STATUS_ADDRESS_ERR;
-        }
-	if(ldns_resolver_source(resolver)) {
-		src = ldns_rdf2native_sockaddr_storage_port(
-				ldns_resolver_source(resolver), 0, &src_len);
-	}
-        /* For AXFR, we have to make the connection ourselves */
-        /* try all nameservers (which usually would mean v4 fallback if
-         * @hostname is used */
-        for (ns_i = 0;
-             ns_i < ldns_resolver_nameserver_count(resolver) &&
-             resolver->_socket == 0;
-             ns_i++) {
-		if (ns != NULL) {
-			LDNS_FREE(ns);
-		}
-	        ns = ldns_rdf2native_sockaddr_storage(
-	        	resolver->_nameservers[ns_i],
-			ldns_resolver_port(resolver), &ns_len);
-
-		resolver->_socket = ldns_tcp_connect_from(
-				ns, (socklen_t)ns_len,
-				src, (socklen_t)src_len,
-				ldns_resolver_timeout(resolver));
-	}
-
-	if (resolver->_socket == 0) {
-		ldns_pkt_free(query);
-		LDNS_FREE(ns);
-		return LDNS_STATUS_NETWORK_ERR;
-	}
-
-#ifdef HAVE_SSL
-	if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
-		status = ldns_pkt_tsig_sign(query,
-		                            ldns_resolver_tsig_keyname(resolver),
-		                            ldns_resolver_tsig_keydata(resolver),
-		                            300, ldns_resolver_tsig_algorithm(resolver), NULL);
-		if (status != LDNS_STATUS_OK) {
-			/* to prevent problems on subsequent calls to 
-			 * ldns_axfr_start we have to close the socket here! */
-#ifndef USE_WINSOCK
-			close(resolver->_socket);
-#else
-			closesocket(resolver->_socket);
-#endif
-			resolver->_socket = 0;
-
-			ldns_pkt_free(query);
-			LDNS_FREE(ns);
-
-			return LDNS_STATUS_CRYPTO_TSIG_ERR;
-		}
-	}
-#endif /* HAVE_SSL */
-
-        /* Convert the query to a buffer
-         * Is this necessary?
-         */
-        query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-        if(!query_wire) {
-                ldns_pkt_free(query);
-                LDNS_FREE(ns);
-#ifndef USE_WINSOCK
-		close(resolver->_socket);
-#else
-		closesocket(resolver->_socket);
-#endif
-		resolver->_socket = 0;
-
-                return LDNS_STATUS_MEM_ERR;
-        }
-        status = ldns_pkt2buffer_wire(query_wire, query);
-        if (status != LDNS_STATUS_OK) {
-                ldns_pkt_free(query);
-		ldns_buffer_free(query_wire);
-                LDNS_FREE(ns);
-
-		/* to prevent problems on subsequent calls to ldns_axfr_start
-		 * we have to close the socket here! */
-#ifndef USE_WINSOCK
-		close(resolver->_socket);
-#else
-		closesocket(resolver->_socket);
-#endif
-		resolver->_socket = 0;
-
-                return status;
-        }
-        /* Send the query */
-        if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
-				(socklen_t)ns_len) == 0) {
-                ldns_pkt_free(query);
-                ldns_buffer_free(query_wire);
-                LDNS_FREE(ns);
-
-		/* to prevent problems on subsequent calls to ldns_axfr_start
-		 * we have to close the socket here! */
-
-#ifndef USE_WINSOCK
-		close(resolver->_socket);
-#else
-		closesocket(resolver->_socket);
-#endif
-		resolver->_socket = 0;
-
-                return LDNS_STATUS_NETWORK_ERR;
-        }
-
-        ldns_pkt_free(query);
-        ldns_buffer_free(query_wire);
-        LDNS_FREE(ns);
-
-        /*
-         * The AXFR is done once the second SOA record is sent
-         */
-        resolver->_axfr_soa_count = 0;
-        return LDNS_STATUS_OK;
-}
diff --git a/src/ldns/packet.c b/src/ldns/packet.c
deleted file mode 100644
index 62bfd07..0000000
--- a/src/ldns/packet.c
+++ /dev/null
@@ -1,1159 +0,0 @@
-/*
- * packet.c
- *
- * dns packet implementation
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <strings.h>
-#include <limits.h>
-
-#ifdef HAVE_SSL
-#include <openssl/rand.h>
-#endif
-
-/* Access functions 
- * do this as functions to get type checking
- */
-
-#define LDNS_EDNS_MASK_DO_BIT 0x8000
-
-/* TODO defines for 3600 */
-/* convert to and from numerical flag values */
-ldns_lookup_table ldns_edns_flags[] = {
-	{ 3600, "do"},
-	{ 0, NULL}
-};
-
-/* read */
-uint16_t
-ldns_pkt_id(const ldns_pkt *packet)
-{
-	return packet->_header->_id;
-}
-
-bool
-ldns_pkt_qr(const ldns_pkt *packet)
-{
-	return packet->_header->_qr;
-}
-
-bool
-ldns_pkt_aa(const ldns_pkt *packet)
-{
-	return packet->_header->_aa;
-}
-
-bool
-ldns_pkt_tc(const ldns_pkt *packet)
-{
-	return packet->_header->_tc;
-}
-
-bool
-ldns_pkt_rd(const ldns_pkt *packet)
-{
-	return packet->_header->_rd;
-}
-
-bool
-ldns_pkt_cd(const ldns_pkt *packet)
-{
-	return packet->_header->_cd;
-}
-
-bool
-ldns_pkt_ra(const ldns_pkt *packet)
-{
-	return packet->_header->_ra;
-}
-
-bool
-ldns_pkt_ad(const ldns_pkt *packet)
-{
-	return packet->_header->_ad;
-}
-
-ldns_pkt_opcode
-ldns_pkt_get_opcode(const ldns_pkt *packet)
-{
-	return packet->_header->_opcode;
-}
-
-ldns_pkt_rcode
-ldns_pkt_get_rcode(const ldns_pkt *packet)
-{
-	return packet->_header->_rcode;
-}
-
-uint16_t
-ldns_pkt_qdcount(const ldns_pkt *packet)
-{
-	return packet->_header->_qdcount;
-}
-
-uint16_t
-ldns_pkt_ancount(const ldns_pkt *packet)
-{
-	return packet->_header->_ancount;
-}
-
-uint16_t
-ldns_pkt_nscount(const ldns_pkt *packet)
-{
-	return packet->_header->_nscount;
-}
-
-uint16_t
-ldns_pkt_arcount(const ldns_pkt *packet)
-{
-	return packet->_header->_arcount;
-}
-
-ldns_rr_list *
-ldns_pkt_question(const ldns_pkt *packet)
-{
-	return packet->_question;
-}
-
-ldns_rr_list *
-ldns_pkt_answer(const ldns_pkt *packet)
-{
-	return packet->_answer;
-}
-
-ldns_rr_list *
-ldns_pkt_authority(const ldns_pkt *packet)
-{
-	return packet->_authority;
-}
-
-ldns_rr_list *
-ldns_pkt_additional(const ldns_pkt *packet)
-{
-	return packet->_additional;
-}
-
-/* return ALL section concatenated */
-ldns_rr_list *
-ldns_pkt_all(const ldns_pkt *packet)
-{
-	ldns_rr_list *all, *prev_all;
-
-	all = ldns_rr_list_cat_clone(
-			ldns_pkt_question(packet),
-			ldns_pkt_answer(packet));
-	prev_all = all;
-	all = ldns_rr_list_cat_clone(all,
-			ldns_pkt_authority(packet));
-	ldns_rr_list_deep_free(prev_all);
-	prev_all = all;
-	all = ldns_rr_list_cat_clone(all,
-			ldns_pkt_additional(packet));
-	ldns_rr_list_deep_free(prev_all);
-	return all;
-}
-
-ldns_rr_list *
-ldns_pkt_all_noquestion(const ldns_pkt *packet)
-{
-	ldns_rr_list *all, *all2;
-
-	all = ldns_rr_list_cat_clone(
-			ldns_pkt_answer(packet),
-			ldns_pkt_authority(packet));
-	all2 = ldns_rr_list_cat_clone(all,
-			ldns_pkt_additional(packet));
-	
-	ldns_rr_list_deep_free(all);
-	return all2;
-}
-
-size_t
-ldns_pkt_size(const ldns_pkt *packet)
-{
-	return packet->_size;
-}
-
-uint32_t 
-ldns_pkt_querytime(const ldns_pkt *packet)
-{
-	return packet->_querytime;
-}
-
-ldns_rdf *
-ldns_pkt_answerfrom(const ldns_pkt *packet)
-{
-	return packet->_answerfrom;
-}
-
-struct timeval
-ldns_pkt_timestamp(const ldns_pkt *packet)
-{
-	return packet->timestamp;
-}
-
-uint16_t
-ldns_pkt_edns_udp_size(const ldns_pkt *packet)
-{
-	return packet->_edns_udp_size;
-}
-
-uint8_t
-ldns_pkt_edns_extended_rcode(const ldns_pkt *packet)
-{
-	return packet->_edns_extended_rcode;
-}
-
-uint8_t
-ldns_pkt_edns_version(const ldns_pkt *packet)
-{
-	return packet->_edns_version;
-}
-
-uint16_t
-ldns_pkt_edns_z(const ldns_pkt *packet)
-{
-	return packet->_edns_z;
-}
-
-bool
-ldns_pkt_edns_do(const ldns_pkt *packet)
-{
-	return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT);
-}
-
-void
-ldns_pkt_set_edns_do(ldns_pkt *packet, bool value)
-{
-	if (value) {
-		packet->_edns_z = packet->_edns_z | LDNS_EDNS_MASK_DO_BIT;
-	} else {
-		packet->_edns_z = packet->_edns_z & ~LDNS_EDNS_MASK_DO_BIT;
-	}
-}
-
-ldns_rdf *
-ldns_pkt_edns_data(const ldns_pkt *packet)
-{
-	return packet->_edns_data;
-}
-
-/* return only those rr that share the ownername */
-ldns_rr_list *
-ldns_pkt_rr_list_by_name(ldns_pkt *packet,
-                         ldns_rdf *ownername,
-                         ldns_pkt_section sec)
-{
-	ldns_rr_list *rrs;
-	ldns_rr_list *ret;
-	uint16_t i;
-
-	if (!packet) {
-		return NULL;
-	}
-
-	rrs = ldns_pkt_get_section_clone(packet, sec);
-	ret = NULL;
-
-	for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
-		if (ldns_dname_compare(ldns_rr_owner(
-						ldns_rr_list_rr(rrs, i)), 
-					ownername) == 0) {
-			/* owner names match */
-			if (ret == NULL) {
-				ret = ldns_rr_list_new();
-			}
-			ldns_rr_list_push_rr(ret,
-					     ldns_rr_clone(
-						ldns_rr_list_rr(rrs, i))
-					    );
-		}
-	}
-
-	ldns_rr_list_deep_free(rrs);
-
-	return ret;
-}
-
-/* return only those rr that share a type */
-ldns_rr_list *
-ldns_pkt_rr_list_by_type(const ldns_pkt *packet,
-                         ldns_rr_type type,
-                         ldns_pkt_section sec)
-{
-	ldns_rr_list *rrs;
-	ldns_rr_list *new;
-	uint16_t i;
-
-	if(!packet) {
-		return NULL;
-	}
-	
-	rrs = ldns_pkt_get_section_clone(packet, sec);
-	new = ldns_rr_list_new();
-	
-	for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
-		if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) {
-			/* types match */
-			ldns_rr_list_push_rr(new, 
-			                     ldns_rr_clone(
-			                     	ldns_rr_list_rr(rrs, i))
-					     );
-		}
-	}
-	ldns_rr_list_deep_free(rrs);
-
-	if (ldns_rr_list_rr_count(new) == 0) {
-		ldns_rr_list_free(new);
-		return NULL;
-	} else {
-		return new;
-	}
-}
-
-/* return only those rrs that share name and type */
-ldns_rr_list *
-ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet,
-                                  const ldns_rdf *ownername,
-                                  ldns_rr_type type,
-                                  ldns_pkt_section sec)
-{
-	ldns_rr_list *rrs;
-	ldns_rr_list *new;
-	ldns_rr_list *ret;
-	uint16_t i;
-
-	if(!packet) {
-		return NULL;
-	}
-	
-	rrs = ldns_pkt_get_section_clone(packet, sec);
-	new = ldns_rr_list_new();
-	ret = NULL;
-
-	for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
-		if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) &&
-		    ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)),
-		                     ownername
-		                    ) == 0
-		   ) {
-			/* types match */
-			ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i)));
-			ret = new;
-		}
-	}
-	ldns_rr_list_deep_free(rrs);
-	if (!ret) {
-		ldns_rr_list_free(new);
-	}
-	return ret;
-}
-
-bool
-ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
-{
-	bool result = false;
-
-	switch (sec) {
-	case LDNS_SECTION_QUESTION:
-		return ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
-	case LDNS_SECTION_ANSWER:
-		return ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr);
-	case LDNS_SECTION_AUTHORITY:
-		return ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr);
-	case LDNS_SECTION_ADDITIONAL:
-		return ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
-	case LDNS_SECTION_ANY:
-		result = ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
-	case LDNS_SECTION_ANY_NOQUESTION:
-		result = result
-		    || ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr)
-		    || ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr)
-		    || ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
-	}
-
-	return result;
-}
-
-uint16_t
-ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s)
-{
-	switch(s) {
-	case LDNS_SECTION_QUESTION:
-		return ldns_pkt_qdcount(packet);
-	case LDNS_SECTION_ANSWER:
-		return ldns_pkt_ancount(packet);
-	case LDNS_SECTION_AUTHORITY:
-		return ldns_pkt_nscount(packet);
-	case LDNS_SECTION_ADDITIONAL:
-		return ldns_pkt_arcount(packet);
-	case LDNS_SECTION_ANY:
-		return ldns_pkt_qdcount(packet) +
-			ldns_pkt_ancount(packet) +
-			ldns_pkt_nscount(packet) +
-			ldns_pkt_arcount(packet);
-	case LDNS_SECTION_ANY_NOQUESTION:
-		return ldns_pkt_ancount(packet) +
-			ldns_pkt_nscount(packet) +
-			ldns_pkt_arcount(packet);
-	default:
-		return 0;
-	}
-}
-
-bool
-ldns_pkt_empty(ldns_pkt *p)
-{
-	if (!p) {
-		return true; /* NULL is empty? */
-	}
-	if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) {
-		return false;
-	} else {
-		return true;
-    }
-}
-
-
-ldns_rr_list *
-ldns_pkt_get_section_clone(const ldns_pkt *packet, ldns_pkt_section s)
-{
-	switch(s) {
-	case LDNS_SECTION_QUESTION:
-		return ldns_rr_list_clone(ldns_pkt_question(packet));
-	case LDNS_SECTION_ANSWER:
-		return ldns_rr_list_clone(ldns_pkt_answer(packet));
-	case LDNS_SECTION_AUTHORITY:
-		return ldns_rr_list_clone(ldns_pkt_authority(packet));
-	case LDNS_SECTION_ADDITIONAL:
-		return ldns_rr_list_clone(ldns_pkt_additional(packet));
-	case LDNS_SECTION_ANY:
-		/* these are already clones */
-		return ldns_pkt_all(packet);
-	case LDNS_SECTION_ANY_NOQUESTION:
-		return ldns_pkt_all_noquestion(packet);
-	default:
-		return NULL;
-	}
-}
-
-ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) {
-	return pkt->_tsig_rr;
-}
-
-/* write */
-void
-ldns_pkt_set_id(ldns_pkt *packet, uint16_t id)
-{
-	packet->_header->_id = id;
-}
-
-void
-ldns_pkt_set_random_id(ldns_pkt *packet)
-{
-	uint16_t rid = ldns_get_random();
-	ldns_pkt_set_id(packet, rid);
-}
-
-
-void
-ldns_pkt_set_qr(ldns_pkt *packet, bool qr)
-{
-	packet->_header->_qr = qr;
-}
-
-void
-ldns_pkt_set_aa(ldns_pkt *packet, bool aa)
-{
-	packet->_header->_aa = aa;
-}
-
-void
-ldns_pkt_set_tc(ldns_pkt *packet, bool tc)
-{
-	packet->_header->_tc = tc;
-}
-
-void
-ldns_pkt_set_rd(ldns_pkt *packet, bool rd)
-{
-	packet->_header->_rd = rd;
-}
-
-void
-ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr)
-{
-	p->_additional = rr;
-}
-
-void
-ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr)
-{
-	p->_question = rr;
-}
-
-void
-ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr)
-{
-	p->_answer = rr;
-}
-
-void
-ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr)
-{
-	p->_authority = rr;
-}
-
-void
-ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
-{
-	packet->_header->_cd = cd;
-}
-
-void
-ldns_pkt_set_ra(ldns_pkt *packet, bool ra)
-{
-	packet->_header->_ra = ra;
-}
-
-void
-ldns_pkt_set_ad(ldns_pkt *packet, bool ad)
-{
-	packet->_header->_ad = ad;
-}
-
-void
-ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode)
-{
-	packet->_header->_opcode = opcode;
-}
-
-void
-ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode)
-{
-	packet->_header->_rcode = rcode;
-}
-
-void
-ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount)
-{
-	packet->_header->_qdcount = qdcount;
-}
-
-void
-ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount)
-{
-	packet->_header->_ancount = ancount;
-}
-
-void
-ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount)
-{
-	packet->_header->_nscount = nscount;
-}
-
-void
-ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount)
-{
-	packet->_header->_arcount = arcount;
-}
-
-void
-ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 
-{
-	packet->_querytime = time;
-}
-
-void
-ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
-{
-	packet->_answerfrom = answerfrom;
-}
-
-void
-ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
-{
-	packet->timestamp.tv_sec = timeval.tv_sec;
-	packet->timestamp.tv_usec = timeval.tv_usec;
-}
-
-void
-ldns_pkt_set_size(ldns_pkt *packet, size_t s)
-{
-	packet->_size = s;
-}
-
-void
-ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s)
-{
-	packet->_edns_udp_size = s;
-}
-
-void
-ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c)
-{
-	packet->_edns_extended_rcode = c;
-}
-
-void
-ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v)
-{
-	packet->_edns_version = v;
-}
-
-void
-ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z)
-{
-	packet->_edns_z = z;
-}
-
-void
-ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data)
-{
-	packet->_edns_data = data;
-}
-
-void
-ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count)
-{
-	switch(s) {
-		case LDNS_SECTION_QUESTION:
-			ldns_pkt_set_qdcount(packet, count);
-			break;
-		case LDNS_SECTION_ANSWER:
-			ldns_pkt_set_ancount(packet, count);
-			break;
-		case LDNS_SECTION_AUTHORITY:
-			ldns_pkt_set_nscount(packet, count);
-			break;
-		case LDNS_SECTION_ADDITIONAL:
-			ldns_pkt_set_arcount(packet, count);
-			break;
-		case LDNS_SECTION_ANY:
-		case LDNS_SECTION_ANY_NOQUESTION:
-			break;
-	}
-}
-
-void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr)
-{
-	pkt->_tsig_rr = rr;
-}
-
-bool
-ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr)
-{
-	switch(section) {
-		case LDNS_SECTION_QUESTION:
-			if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
-				return false;
-			}
-			ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1);
-			break;
-		case LDNS_SECTION_ANSWER:
-			if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
-				return false;
-			}
-			ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1);
-			break;
-		case LDNS_SECTION_AUTHORITY:
-			if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
-				return false;
-			}
-			ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1);
-			break;
-		case LDNS_SECTION_ADDITIONAL:
-			if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
-				return false;
-			}
-			ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1);
-			break;
-		case LDNS_SECTION_ANY:
-		case LDNS_SECTION_ANY_NOQUESTION:
-			/* shouldn't this error? */
-			break;
-	}
-	return true;
-}
-
-bool
-ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
-{
-
-	/* check to see if its there */
-	if (ldns_pkt_rr(pkt, sec, rr)) {
-		/* already there */
-		return false;
-	}
-	return ldns_pkt_push_rr(pkt, sec, rr);
-}
-
-bool
-ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
-{
-	size_t i;
-	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
-		if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) {
-			return false;
-		}
-	}
-	return true;
-}
-
-bool
-ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
-{
-	size_t i;
-	for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
-		if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) {
-			return false;
-		}
-	}
-	return true;
-}
-
-bool
-ldns_pkt_edns(const ldns_pkt *pkt) {
-	return (ldns_pkt_edns_udp_size(pkt) > 0 ||
-		ldns_pkt_edns_extended_rcode(pkt) > 0 ||
-		ldns_pkt_edns_data(pkt) ||
-		ldns_pkt_edns_do(pkt) ||
-                pkt->_edns_present
-	       );
-}
-
-
-/* Create/destroy/convert functions
- */
-ldns_pkt *
-ldns_pkt_new(void)
-{
-	ldns_pkt *packet;
-	packet = LDNS_MALLOC(ldns_pkt);
-	if (!packet) {
-		return NULL;
-	}
-
-	packet->_header = LDNS_MALLOC(ldns_hdr);
-	if (!packet->_header) {
-		LDNS_FREE(packet);
-		return NULL;
-	}
-
-	packet->_question = ldns_rr_list_new();
-	packet->_answer = ldns_rr_list_new();
-	packet->_authority = ldns_rr_list_new();
-	packet->_additional = ldns_rr_list_new();
-
-	/* default everything to false */
-	ldns_pkt_set_qr(packet, false);
-	ldns_pkt_set_aa(packet, false);
-	ldns_pkt_set_tc(packet, false);
-	ldns_pkt_set_rd(packet, false);
-	ldns_pkt_set_ra(packet, false);
-	ldns_pkt_set_ad(packet, false);
-	ldns_pkt_set_cd(packet, false);
-
-	ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY);
-	ldns_pkt_set_rcode(packet, 0);
-	ldns_pkt_set_id(packet, 0); 
-	ldns_pkt_set_size(packet, 0);
-	ldns_pkt_set_querytime(packet, 0);
-	memset(&packet->timestamp, 0, sizeof(packet->timestamp));
-	ldns_pkt_set_answerfrom(packet, NULL);
-	ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0);
-	ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0);
-	ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0);
-	ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0);
-	
-	ldns_pkt_set_edns_udp_size(packet, 0);
-	ldns_pkt_set_edns_extended_rcode(packet, 0);
-	ldns_pkt_set_edns_version(packet, 0);
-	ldns_pkt_set_edns_z(packet, 0);
-	ldns_pkt_set_edns_data(packet, NULL);
-	packet->_edns_present = false;
-	
-	ldns_pkt_set_tsig(packet, NULL);
-	
-	return packet;
-}
-
-void
-ldns_pkt_free(ldns_pkt *packet)
-{
-	if (packet) {
-		LDNS_FREE(packet->_header);
-		ldns_rr_list_deep_free(packet->_question);
-		ldns_rr_list_deep_free(packet->_answer);
-		ldns_rr_list_deep_free(packet->_authority);
-		ldns_rr_list_deep_free(packet->_additional);
-		ldns_rr_free(packet->_tsig_rr);
-		ldns_rdf_deep_free(packet->_edns_data);
-		ldns_rdf_deep_free(packet->_answerfrom);
-		LDNS_FREE(packet);
-	}
-}
-
-bool
-ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags)
-{
-	if (!packet) {
-		return false;
-	}
-	if ((flags & LDNS_QR) == LDNS_QR) {
-		ldns_pkt_set_qr(packet, true);
-	}
-	if ((flags & LDNS_AA) == LDNS_AA) {
-		ldns_pkt_set_aa(packet, true);
-	}
-	if ((flags & LDNS_RD) == LDNS_RD) {
-		ldns_pkt_set_rd(packet, true);
-	}
-	if ((flags & LDNS_TC) == LDNS_TC) {
-		ldns_pkt_set_tc(packet, true);
-	}
-	if ((flags & LDNS_CD) == LDNS_CD) {
-		ldns_pkt_set_cd(packet, true);
-	}
-	if ((flags & LDNS_RA) == LDNS_RA) {
-		ldns_pkt_set_ra(packet, true);
-	}
-	if ((flags & LDNS_AD) == LDNS_AD) {
-		ldns_pkt_set_ad(packet, true);
-	}
-	return true;
-}
-
-
-static ldns_rr*
-ldns_pkt_authsoa(ldns_rdf* rr_name, ldns_rr_class rr_class)
-{
-	ldns_rr* soa_rr = ldns_rr_new();
-	ldns_rdf *owner_rdf;
-	ldns_rdf *mname_rdf;
-	ldns_rdf *rname_rdf;
-	ldns_rdf *serial_rdf;
-	ldns_rdf *refresh_rdf;
-	ldns_rdf *retry_rdf;
-	ldns_rdf *expire_rdf;
-	ldns_rdf *minimum_rdf;
-
-	if (!soa_rr) {
-		return NULL;
-	}
-	owner_rdf = ldns_rdf_clone(rr_name);
-	if (!owner_rdf) {
-		ldns_rr_free(soa_rr);
-		return NULL;
-	}
-
-	ldns_rr_set_owner(soa_rr, owner_rdf);
-	ldns_rr_set_type(soa_rr, LDNS_RR_TYPE_SOA);
-	ldns_rr_set_class(soa_rr, rr_class);
-	ldns_rr_set_question(soa_rr, false);
-
-	if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
-		ldns_rr_free(soa_rr);
-		return NULL;
-	} else {
-		ldns_rr_push_rdf(soa_rr, mname_rdf);
-	}
-	if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
-		ldns_rr_free(soa_rr);
-		return NULL;
-	} else {
-		ldns_rr_push_rdf(soa_rr, rname_rdf);
-	}
-	serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-	if (!serial_rdf) {
-		ldns_rr_free(soa_rr);
-		return NULL;
-	} else {
-		ldns_rr_push_rdf(soa_rr, serial_rdf);
-	}
-	refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-	if (!refresh_rdf) {
-		ldns_rr_free(soa_rr);
-		return NULL;
-	} else {
-		ldns_rr_push_rdf(soa_rr, refresh_rdf);
-	}
-	retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-	if (!retry_rdf) {
-		ldns_rr_free(soa_rr);
-		return NULL;
-	} else {
-		ldns_rr_push_rdf(soa_rr, retry_rdf);
-	}
-	expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-	if (!expire_rdf) {
-		ldns_rr_free(soa_rr);
-		return NULL;
-	} else {
-		ldns_rr_push_rdf(soa_rr, expire_rdf);
-	}
-	minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-	if (!minimum_rdf) {
-		ldns_rr_free(soa_rr);
-		return NULL;
-	} else {
-		ldns_rr_push_rdf(soa_rr, minimum_rdf);
-	}
-	return soa_rr;
-}
-
-
-static ldns_status
-ldns_pkt_query_new_frm_str_internal(ldns_pkt **p, const char *name,
-	ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags,
-	ldns_rr* authsoa_rr)
-{
-	ldns_pkt *packet;
-	ldns_rr *question_rr;
-	ldns_rdf *name_rdf;
-
-	packet = ldns_pkt_new();
-	if (!packet) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	if (!ldns_pkt_set_flags(packet, flags)) {
-		return LDNS_STATUS_ERR;
-	}
-
-	question_rr = ldns_rr_new();
-	if (!question_rr) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	if (rr_type == 0) {
-		rr_type = LDNS_RR_TYPE_A;
-	}
-	if (rr_class == 0) {
-		rr_class = LDNS_RR_CLASS_IN;
-	}
-
-	if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
-		ldns_rr_set_owner(question_rr, name_rdf);
-		ldns_rr_set_type(question_rr, rr_type);
-		ldns_rr_set_class(question_rr, rr_class);
-                ldns_rr_set_question(question_rr, true);
-
-		ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
-	} else {
-		ldns_rr_free(question_rr);
-		ldns_pkt_free(packet);
-		return LDNS_STATUS_ERR;
-	}
-
-	if (authsoa_rr) {
-		ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
-	}
-
-	packet->_tsig_rr = NULL;
-	ldns_pkt_set_answerfrom(packet, NULL);
-	if (p) {
-		*p = packet;
-		return LDNS_STATUS_OK;
-	} else {
-		ldns_pkt_free(packet);
-		return LDNS_STATUS_NULL;
-	}
-}
-
-ldns_status
-ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name,
-	ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags)
-{
-	return ldns_pkt_query_new_frm_str_internal(p, name, rr_type,
-		rr_class, flags, NULL);
-}
-
-ldns_status
-ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *name,
-	ldns_rr_class rr_class, uint16_t flags, ldns_rr *soa)
-{
-	ldns_rr* authsoa_rr = soa;
-	if (!authsoa_rr) {
-		ldns_rdf *name_rdf;
-		if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
-			authsoa_rr = ldns_pkt_authsoa(name_rdf, rr_class);
-		}
-		ldns_rdf_free(name_rdf);
-	}
-	return ldns_pkt_query_new_frm_str_internal(p, name, LDNS_RR_TYPE_IXFR,
-		rr_class, flags, authsoa_rr);
-}
-
-static ldns_pkt *
-ldns_pkt_query_new_internal(ldns_rdf *rr_name, ldns_rr_type rr_type,
-	ldns_rr_class rr_class,	uint16_t flags, ldns_rr* authsoa_rr)
-{
-	ldns_pkt *packet;
-	ldns_rr *question_rr;
-
-	packet = ldns_pkt_new();
-	if (!packet) {
-		return NULL;
-	}
-
-	if (!ldns_pkt_set_flags(packet, flags)) {
-		return NULL;
-	}
-
-	question_rr = ldns_rr_new();
-	if (!question_rr) {
-		ldns_pkt_free(packet);
-		return NULL;
-	}
-
-	if (rr_type == 0) {
-		rr_type = LDNS_RR_TYPE_A;
-	}
-	if (rr_class == 0) {
-		rr_class = LDNS_RR_CLASS_IN;
-	}
-
-	ldns_rr_set_owner(question_rr, rr_name);
-	ldns_rr_set_type(question_rr, rr_type);
-	ldns_rr_set_class(question_rr, rr_class);
-        ldns_rr_set_question(question_rr, true);
-	ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
-
-	if (authsoa_rr) {
-		ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
-	}
-
-	packet->_tsig_rr = NULL;
-	return packet;
-}
-
-ldns_pkt *
-ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type,
-	ldns_rr_class rr_class,	uint16_t flags)
-{
-	return ldns_pkt_query_new_internal(rr_name, rr_type,
-		rr_class, flags, NULL);
-}
-
-ldns_pkt *
-ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class,
-	uint16_t flags, ldns_rr* soa)
-{
-	ldns_rr* authsoa_rr = soa;
-	if (!authsoa_rr) {
-		authsoa_rr = ldns_pkt_authsoa(rr_name, rr_class);
-	}
-	return ldns_pkt_query_new_internal(rr_name, LDNS_RR_TYPE_IXFR,
-		rr_class, flags, authsoa_rr);
-}
-
-ldns_pkt_type
-ldns_pkt_reply_type(ldns_pkt *p)
-{
-	ldns_rr_list *tmp;
-
-	if (!p) {
-		return LDNS_PACKET_UNKNOWN;
-	}
-
-	if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) {
-		return LDNS_PACKET_NXDOMAIN;
-	}
-
-	if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0
-			&& ldns_pkt_nscount(p) == 1) {
-
-		/* check for SOA */
-		tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, 
-					LDNS_SECTION_AUTHORITY);
-		if (tmp) {
-			ldns_rr_list_deep_free(tmp);
-			return LDNS_PACKET_NODATA;
-		} else {
-			/* I have no idea ... */
-		}
-	}
-
-	if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) {
-		tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS,
-		                               LDNS_SECTION_AUTHORITY);
-		if (tmp) {
-			/* there are nameservers here */
-			ldns_rr_list_deep_free(tmp);
-			return LDNS_PACKET_REFERRAL;
-		} else {
-			/* I have no idea */
-		}
-		ldns_rr_list_deep_free(tmp);
-	}
-	
-	/* if we cannot determine the packet type, we say it's an 
-	 * answer...
-	 */
-	return LDNS_PACKET_ANSWER;
-}
-
-ldns_pkt *
-ldns_pkt_clone(const ldns_pkt *pkt)
-{
-	ldns_pkt *new_pkt;
-	
-	if (!pkt) {
-		return NULL;
-	}
-	new_pkt = ldns_pkt_new();
-
-	ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt));
-	ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt));
-	ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt));
-	ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt));
-	ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt));
-	ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt));
-	ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt));
-	ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt));
-	ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt));
-	ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt));
-	ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt));
-	ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt));
-	ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt));
-	ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt));
-	if (ldns_pkt_answerfrom(pkt))
-		ldns_pkt_set_answerfrom(new_pkt,
-			ldns_rdf_clone(ldns_pkt_answerfrom(pkt)));
-	ldns_pkt_set_timestamp(new_pkt, ldns_pkt_timestamp(pkt));
-	ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
-	ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
-	ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt)));
-	
-	ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt));
-	ldns_pkt_set_edns_extended_rcode(new_pkt, 
-		ldns_pkt_edns_extended_rcode(pkt));
-	ldns_pkt_set_edns_version(new_pkt, ldns_pkt_edns_version(pkt));
-	new_pkt->_edns_present = pkt->_edns_present;
-	ldns_pkt_set_edns_z(new_pkt, ldns_pkt_edns_z(pkt));
-	if(ldns_pkt_edns_data(pkt))
-		ldns_pkt_set_edns_data(new_pkt, 
-			ldns_rdf_clone(ldns_pkt_edns_data(pkt)));
-	ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt));
-
-	ldns_rr_list_deep_free(new_pkt->_question);
-	ldns_rr_list_deep_free(new_pkt->_answer);
-	ldns_rr_list_deep_free(new_pkt->_authority);
-	ldns_rr_list_deep_free(new_pkt->_additional);
-	new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt));
-	new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt));
-	new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt));
-	new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt));
-	return new_pkt;
-}
diff --git a/src/ldns/parse.c b/src/ldns/parse.c
deleted file mode 100644
index e68627c..0000000
--- a/src/ldns/parse.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * a generic (simple) parser. Use to parse rr's, private key
- * information and /etc/resolv.conf files
- *
- * a Net::DNS like library for C
- * LibDNS Team @ NLnet Labs
- * (c) NLnet Labs, 2005-2006
- * See the file LICENSE for the license
- */
-#include <ldns/config.h>
-#include <ldns/ldns.h>
-
-#include <limits.h>
-#include <strings.h>
-
-ldns_lookup_table ldns_directive_types[] = {
-        { LDNS_DIR_TTL, "$TTL" },
-        { LDNS_DIR_ORIGIN, "$ORIGIN" },
-        { LDNS_DIR_INCLUDE, "$INCLUDE" },
-        { 0, NULL }
-};
-
-/* add max_limit here? */
-ssize_t
-ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit)
-{
-	return ldns_fget_token_l(f, token, delim, limit, NULL);
-}
-
-ssize_t
-ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
-{
-	int c, prev_c;
-	int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
-	int com, quoted;
-	char *t;
-	size_t i;
-	const char *d;
-	const char *del;
-
-	/* standard delimeters */
-	if (!delim) {
-		/* from isspace(3) */
-		del = LDNS_PARSE_NORMAL;
-	} else {
-		del = delim;
-	}
-
-	p = 0;
-	i = 0;
-	com = 0;
-	quoted = 0;
-	prev_c = 0;
-	t = token;
-	if (del[0] == '"') {
-		quoted = 1;
-	}
-	while ((c = getc(f)) != EOF) {
-		if (c == '\r') /* carriage return */
-			c = ' ';
-		if (c == '(' && prev_c != '\\' && !quoted) {
-			/* this only counts for non-comments */
-			if (com == 0) {
-				p++;
-			}
-			prev_c = c;
-			continue;
-		}
-
-		if (c == ')' && prev_c != '\\' && !quoted) {
-			/* this only counts for non-comments */
-			if (com == 0) {
-				p--;
-			}
-			prev_c = c;
-			continue;
-		}
-
-		if (p < 0) {
-			/* more ) then ( - close off the string */
-			*t = '\0';
-			return 0;
-		}
-
-		/* do something with comments ; */
-		if (c == ';' && quoted == 0) {
-			if (prev_c != '\\') {
-				com = 1;
-			}
-		}
-		if (c == '\"' && com == 0 && prev_c != '\\') {
-			quoted = 1 - quoted;
-		}
-
-		if (c == '\n' && com != 0) {
-			/* comments */
-			com = 0;
-			*t = ' ';
-			if (line_nr) {
-				*line_nr = *line_nr + 1;
-			}
-			if (p == 0 && i > 0) {
-				goto tokenread;
-			} else {
-				prev_c = c;
-				continue;
-			}
-		}
-
-		if (com == 1) {
-			*t = ' ';
-			prev_c = c;
-			continue;
-		}
-
-		if (c == '\n' && p != 0 && t > token) {
-			/* in parentheses */
-			if (line_nr) {
-				*line_nr = *line_nr + 1;
-			}
-			*t++ = ' ';
-			prev_c = c;
-			continue;
-		}
-
-		/* check if we hit the delim */
-		for (d = del; *d; d++) {
-			if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
-				if (c == '\n' && line_nr) {
-					*line_nr = *line_nr + 1;
-				}
-				goto tokenread;
-			}
-		}
-		if (c != '\0' && c != '\n') {
-			i++;
-		}
-		if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
-			*t = '\0';
-			return -1;
-		}
-		if (c != '\0' && c != '\n') {
-			*t++ = c;
-		}
-		if (c == '\\' && prev_c == '\\')
-			prev_c = 0;
-		else	prev_c = c;
-	}
-	*t = '\0';
-	if (c == EOF) {
-		return (ssize_t)i;
-	}
-
-	if (i == 0) {
-		/* nothing read */
-		return -1;
-	}
-	if (p != 0) {
-		return -1;
-	}
-	return (ssize_t)i;
-
-tokenread:
-	if(*del == '"') /* do not skip over quotes, they are significant */
-		ldns_fskipcs_l(f, del+1, line_nr);
-	else	ldns_fskipcs_l(f, del, line_nr);
-	*t = '\0';
-	if (p != 0) {
-		return -1;
-	}
-
-	return (ssize_t)i;
-}
-
-ssize_t
-ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data,
-               const char *d_del, size_t data_limit)
-{
-       return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del,
-		       data_limit, NULL);
-}
-
-ssize_t
-ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data,
-               const char *d_del, size_t data_limit, int *line_nr)
-{
-       /* we assume: keyword|sep|data */
-       char *fkeyword;
-       ssize_t i;
-
-       if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
-               return -1;
-       fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
-       if(!fkeyword)
-               return -1;
-
-       i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
-       if(i==0 || i==-1) {
-               LDNS_FREE(fkeyword);
-               return -1;
-       }
-
-       /* case??? i instead of strlen? */
-       if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
-               /* whee! */
-               /* printf("%s\n%s\n", "Matching keyword", fkeyword); */
-               i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr);
-               LDNS_FREE(fkeyword);
-               return i;
-       } else {
-               /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/
-               LDNS_FREE(fkeyword);
-               return -1;
-       }
-}
-
-
-ssize_t
-ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
-{
-	int c, lc;
-	int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
-	int com, quoted;
-	char *t;
-	size_t i;
-	const char *d;
-	const char *del;
-
-	/* standard delimiters */
-	if (!delim) {
-		/* from isspace(3) */
-		del = LDNS_PARSE_NORMAL;
-	} else {
-		del = delim;
-	}
-
-	p = 0;
-	i = 0;
-	com = 0;
-	quoted = 0;
-	t = token;
-	lc = 0;
-	if (del[0] == '"') {
-		quoted = 1;
-	}
-
-	while ((c = ldns_bgetc(b)) != EOF) {
-		if (c == '\r') /* carriage return */
-			c = ' ';
-		if (c == '(' && lc != '\\' && !quoted) {
-			/* this only counts for non-comments */
-			if (com == 0) {
-				p++;
-			}
-			lc = c;
-			continue;
-		}
-
-		if (c == ')' && lc != '\\' && !quoted) {
-			/* this only counts for non-comments */
-			if (com == 0) {
-				p--;
-			}
-			lc = c;
-			continue;
-		}
-
-		if (p < 0) {
-			/* more ) then ( */
-			*t = '\0';
-			return 0;
-		}
-
-		/* do something with comments ; */
-		if (c == ';' && quoted == 0) {
-			if (lc != '\\') {
-				com = 1;
-			}
-		}
-		if (c == '"' && com == 0 && lc != '\\') {
-			quoted = 1 - quoted;
-		}
-
-		if (c == '\n' && com != 0) {
-			/* comments */
-			com = 0;
-			*t = ' ';
-			lc = c;
-			continue;
-		}
-
-		if (com == 1) {
-			*t = ' ';
-			lc = c;
-			continue;
-		}
-
-		if (c == '\n' && p != 0) {
-			/* in parentheses */
-			*t++ = ' ';
-			lc = c;
-			continue;
-		}
-
-		/* check if we hit the delim */
-		for (d = del; *d; d++) {
-                        if (c == *d && lc != '\\' && p == 0) {
-				goto tokenread;
-                        }
-		}
-
-		i++;
-		if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
-			*t = '\0';
-			return -1;
-		}
-		*t++ = c;
-
-		if (c == '\\' && lc == '\\') {
-			lc = 0;
-		} else {
-			lc = c;
-		}
-	}
-	*t = '\0';
-	if (i == 0) {
-		/* nothing read */
-		return -1;
-	}
-	if (p != 0) {
-		return -1;
-	}
-	return (ssize_t)i;
-
-tokenread:
-	if(*del == '"') /* do not skip over quotes, they are significant */
-		ldns_bskipcs(b, del+1);
-	else	ldns_bskipcs(b, del);
-	*t = '\0';
-
-	if (p != 0) {
-		return -1;
-	}
-	return (ssize_t)i;
-}
-
-
-void
-ldns_bskipcs(ldns_buffer *buffer, const char *s)
-{
-        bool found;
-        char c;
-        const char *d;
-
-        while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) {
-                c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position);
-                found = false;
-                for (d = s; *d; d++) {
-                        if (*d == c) {
-                                found = true;
-                        }
-                }
-                if (found && buffer->_limit > buffer->_position) {
-                        buffer->_position += sizeof(char);
-                } else {
-                        return;
-                }
-        }
-}
-
-void
-ldns_fskipcs(FILE *fp, const char *s)
-{
-	ldns_fskipcs_l(fp, s, NULL);
-}
-
-void
-ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr)
-{
-        bool found;
-        int c;
-        const char *d;
-
-	while ((c = fgetc(fp)) != EOF) {
-		if (line_nr && c == '\n') {
-			*line_nr = *line_nr + 1;
-		}
-                found = false;
-                for (d = s; *d; d++) {
-                        if (*d == c) {
-                                found = true;
-                        }
-                }
-		if (!found) {
-			/* with getc, we've read too far */
-			ungetc(c, fp);
-			return;
-		}
-	}
-}
-
-ssize_t
-ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char
-*data, const char *d_del, size_t data_limit)
-{
-       /* we assume: keyword|sep|data */
-       char *fkeyword;
-       ssize_t i;
-
-       if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
-               return -1;
-       fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
-       if(!fkeyword)
-               return -1; /* out of memory */
-
-       i = ldns_bget_token(b, fkeyword, k_del, data_limit);
-       if(i==0 || i==-1) {
-               LDNS_FREE(fkeyword);
-               return -1; /* nothing read */
-       }
-
-       /* case??? */
-       if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
-               LDNS_FREE(fkeyword);
-               /* whee, the match! */
-               /* retrieve it's data */
-               i = ldns_bget_token(b, data, d_del, 0);
-               return i;
-       } else {
-               LDNS_FREE(fkeyword);
-               return -1;
-       }
-}
-
diff --git a/src/ldns/radix.c b/src/ldns/radix.c
deleted file mode 100644
index 7aac258..0000000
--- a/src/ldns/radix.c
+++ /dev/null
@@ -1,1590 +0,0 @@
-/*
- * radix.c -- generic radix tree
- *
- * Taken from NSD4, modified for ldns
- *
- * Copyright (c) 2012, NLnet Labs. All rights reserved.
- *
- * This software is open source.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NLNET LABS nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * \file
- * Implementation of a radix tree.
- */
-
-#include <ldns/config.h>
-#include <ldns/radix.h>
-#include <ldns/util.h>
-#include <stdlib.h>
-
-/** Helper functions */
-static ldns_radix_node_t* ldns_radix_new_node(void* data, uint8_t* key,
-	radix_strlen_t len);
-static int ldns_radix_find_prefix(ldns_radix_t* tree, uint8_t* key,
-	radix_strlen_t len, ldns_radix_node_t** result, radix_strlen_t* pos);
-static int ldns_radix_array_space(ldns_radix_node_t* node, uint8_t byte);
-static int ldns_radix_array_grow(ldns_radix_node_t* node, unsigned need);
-static int ldns_radix_str_create(ldns_radix_array_t* array, uint8_t* key,
-	radix_strlen_t pos, radix_strlen_t len);
-static int ldns_radix_prefix_remainder(radix_strlen_t prefix_len,
-	uint8_t* longer_str, radix_strlen_t longer_len, uint8_t** split_str,
-	radix_strlen_t* split_len);
-static int ldns_radix_array_split(ldns_radix_array_t* array, uint8_t* key,
-	radix_strlen_t pos, radix_strlen_t len, ldns_radix_node_t* add);
-static int ldns_radix_str_is_prefix(uint8_t* str1, radix_strlen_t len1,
-	uint8_t* str2, radix_strlen_t len2);
-static radix_strlen_t ldns_radix_str_common(uint8_t* str1, radix_strlen_t len1,
-	uint8_t* str2, radix_strlen_t len2);
-static ldns_radix_node_t* ldns_radix_next_in_subtree(ldns_radix_node_t* node);
-static ldns_radix_node_t* ldns_radix_prev_from_index(ldns_radix_node_t* node,
-	uint8_t index);
-static ldns_radix_node_t* ldns_radix_last_in_subtree_incl_self(
-	ldns_radix_node_t* node);
-static ldns_radix_node_t* ldns_radix_last_in_subtree(ldns_radix_node_t* node);
-static void ldns_radix_del_fix(ldns_radix_t* tree, ldns_radix_node_t* node);
-static void ldns_radix_cleanup_onechild(ldns_radix_node_t* node);
-static void ldns_radix_cleanup_leaf(ldns_radix_node_t* node);
-static void ldns_radix_node_free(ldns_radix_node_t* node, void* arg);
-static void ldns_radix_node_array_free(ldns_radix_node_t* node);
-static void ldns_radix_node_array_free_front(ldns_radix_node_t* node);
-static void ldns_radix_node_array_free_end(ldns_radix_node_t* node);
-static void ldns_radix_array_reduce(ldns_radix_node_t* node);
-static void ldns_radix_self_or_prev(ldns_radix_node_t* node,
-	ldns_radix_node_t** result);
-
-
-/**
- * Create a new radix node.
- *
- */
-static ldns_radix_node_t*
-ldns_radix_new_node(void* data, uint8_t* key, radix_strlen_t len)
-{
-	ldns_radix_node_t* node = LDNS_MALLOC(ldns_radix_node_t);
-	if (!node) {
-		return NULL;
-	}
-	node->data = data;
-	node->key = key;
-	node->klen = len;
-	node->parent = NULL;
-	node->parent_index = 0;
-	node->len = 0;
-	node->offset = 0;
-	node->capacity = 0;
-	node->array = NULL;
-	return node;
-}
-
-
-/**
- * Create a new radix tree.
- *
- */
-ldns_radix_t *
-ldns_radix_create(void)
-{
-	ldns_radix_t* tree;
-
-	/** Allocate memory for it */
-	tree = (ldns_radix_t *) LDNS_MALLOC(ldns_radix_t);
-	if (!tree) {
-		return NULL;
-	}
-	/** Initialize it */
-	ldns_radix_init(tree);
-	return tree;
-}
-
-
-/**
- * Initialize radix tree.
- *
- */
-void
-ldns_radix_init(ldns_radix_t* tree)
-{
-	/** Initialize it */
-	if (tree) {
-		tree->root = NULL;
-		tree->count = 0;
-	}
-	return;
-}
-
-
-/**
- * Free radix tree.
- *
- */
-void
-ldns_radix_free(ldns_radix_t* tree)
-{
-	if (tree) {
-		if (tree->root) {
-			ldns_radix_traverse_postorder(tree->root,
-				ldns_radix_node_free, NULL);
-		}
-		LDNS_FREE(tree);
-	}
-	return;
-}
-
-
-/**
- * Insert data into the tree.
- *
- */
-ldns_status
-ldns_radix_insert(ldns_radix_t* tree, uint8_t* key, radix_strlen_t len,
-	void* data)
-{
-	radix_strlen_t pos = 0;
-	ldns_radix_node_t* add = NULL;
-	ldns_radix_node_t* prefix = NULL;
-
-	if (!tree || !key || !data) {
-		return LDNS_STATUS_NULL;
-	}
-	add = ldns_radix_new_node(data, key, len);
-	if (!add) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	/** Search the trie until we can make no further process. */
-	if (!ldns_radix_find_prefix(tree, key, len, &prefix, &pos)) {
-		/** No prefix found */
-		assert(tree->root == NULL);
-		if (len == 0) {
-			/**
-			 * Example 1: The root:
-			 * | [0]
-			 **/
-			tree->root = add;
-		} else {
-			/** Example 2: 'dns':
-			 * | [0]
-			 * --| [d+ns] dns
-			 **/
-			prefix = ldns_radix_new_node(NULL, (uint8_t*)"", 0);
-			if (!prefix) {
-				LDNS_FREE(add);
-				return LDNS_STATUS_MEM_ERR;
-			}
-			/** Find some space in the array for the first byte */
-			if (!ldns_radix_array_space(prefix, key[0])) {
-				LDNS_FREE(add);
-				LDNS_FREE(prefix->array);
-				LDNS_FREE(prefix);
-				return LDNS_STATUS_MEM_ERR;
-			}
-			/** Set relational pointers */
-			add->parent = prefix;
-			add->parent_index = 0;
-			prefix->array[0].edge = add;
-			if (len > 1) {
-				/** Store the remainder of the prefix */
-				if (!ldns_radix_prefix_remainder(1, key,
-					len, &prefix->array[0].str,
-					&prefix->array[0].len)) {
-					LDNS_FREE(add);
-					LDNS_FREE(prefix->array);
-					LDNS_FREE(prefix);
-					return LDNS_STATUS_MEM_ERR;
-				}
-			}
-			tree->root = prefix;
-		}
-	} else if (pos == len) {
-		/** Exact match found */
-		if (prefix->data) {
-			/* Element already exists */
-			LDNS_FREE(add);
-			return LDNS_STATUS_EXISTS_ERR;
-		}
-		prefix->data = data;
-		prefix->key = key;
-		prefix->klen = len; /* redundant */
-	} else {
-		/** Prefix found */
-		uint8_t byte = key[pos];
-		assert(pos < len);
-		if (byte < prefix->offset ||
-			(byte - prefix->offset) >= prefix->len) {
-			/** Find some space in the array for the byte. */
-			/**
-			 * Example 3: 'ldns'
-			 * | [0]
-			 * --| [d+ns] dns
-			 * --| [l+dns] ldns
-			 **/
-			if (!ldns_radix_array_space(prefix, byte)) {
-				LDNS_FREE(add);
-				return LDNS_STATUS_MEM_ERR;
-			}
-			assert(byte >= prefix->offset);
-			assert((byte - prefix->offset) <= prefix->len);
-			byte -= prefix->offset;
-			if (pos+1 < len) {
-				/** Create remainder of the string. */
-				if (!ldns_radix_str_create(
-					&prefix->array[byte], key, pos+1,
-					len)) {
-					LDNS_FREE(add);
-					return LDNS_STATUS_MEM_ERR;
-				}
-			}
-			/** Add new node. */
-			add->parent = prefix;
-			add->parent_index = byte;
-			prefix->array[byte].edge = add;
-		} else if (prefix->array[byte-prefix->offset].edge == NULL) {
-			/** Use existing element. */
-			/**
-			 * Example 4: 'edns'
-			 * | [0]
-			 * --| [d+ns] dns
-			 * --| [e+dns] edns
-			 * --| [l+dns] ldns
-			 **/
-			byte -= prefix->offset;
-			if (pos+1 < len) {
-				/** Create remainder of the string. */
-				if (!ldns_radix_str_create(
-					&prefix->array[byte], key, pos+1,
-					len)) {
-					LDNS_FREE(add);
-					return LDNS_STATUS_MEM_ERR;
-				}
-			}
-			/** Add new node. */
-			add->parent = prefix;
-			add->parent_index = byte;
-			prefix->array[byte].edge = add;
-		} else {
-			/**
-			 * Use existing element, but it has a shared prefix,
-			 * we need a split.
-			 */
-			if (!ldns_radix_array_split(&prefix->array[byte-(prefix->offset)],
-				key, pos+1, len, add)) {
-				LDNS_FREE(add);
-				return LDNS_STATUS_MEM_ERR;
-			}
-		}
-	}
-
-	tree->count ++;
-	return LDNS_STATUS_OK;
-}
-
-
-/**
- * Delete data from the tree.
- *
- */
-void* ldns_radix_delete(ldns_radix_t* tree, uint8_t* key, radix_strlen_t len)
-{
-    ldns_radix_node_t* del = ldns_radix_search(tree, key, len);
-    void* data = NULL;
-    if (del) {
-        tree->count--;
-        data = del->data;
-        del->data = NULL;
-        ldns_radix_del_fix(tree, del);
-        return data;
-    }
-    return NULL;
-}
-
-
-/**
- * Search data in the tree.
- *
- */
-ldns_radix_node_t*
-ldns_radix_search(ldns_radix_t* tree, uint8_t* key, radix_strlen_t len)
-{
-	ldns_radix_node_t* node = NULL;
-	radix_strlen_t pos = 0;
-	uint8_t byte = 0;
-
-	if (!tree || !key) {
-		return NULL;
-	}
-	node = tree->root;
-	while (node) {
-		if (pos == len) {
-			return node->data?node:NULL;
-		}
-		byte = key[pos];
-		if (byte < node->offset) {
-			return NULL;
-		}
-		byte -= node->offset;
-		if (byte >= node->len) {
-			return NULL;
-		}
-		pos++;
-		if (node->array[byte].len > 0) {
-			/** Must match additional string. */
-			if (pos + node->array[byte].len > len) {
-				return NULL;
-			}
-			if (memcmp(&key[pos], node->array[byte].str,
-				node->array[byte].len) != 0) {
-				return NULL;
-			}
-			pos += node->array[byte].len;
-		}
-		node = node->array[byte].edge;
-	}
-	return NULL;
-}
-
-
-/**
- * Search data in the tree, and if not found, find the closest smaller
- * element in the tree.
- *
- */
-int
-ldns_radix_find_less_equal(ldns_radix_t* tree, uint8_t* key,
-	radix_strlen_t len, ldns_radix_node_t** result)
-{
-	ldns_radix_node_t* node = NULL;
-	radix_strlen_t pos = 0;
-	uint8_t byte;
-	int memcmp_res = 0;
-
-	if (!tree || !tree->root || !key) {
-		*result = NULL;
-		return 0;
-	}
-
-	node = tree->root;
-	while (pos < len) {
-		byte = key[pos];
-		if (byte < node->offset) {
-			/**
-			 * No exact match. The lesser is in this or the
-			 * previous node.
-			 */
-			ldns_radix_self_or_prev(node, result);
-			return 0;
-		}
-		byte -= node->offset;
-		if (byte >= node->len) {
-			/**
-			 * No exact match. The lesser is in this node or the
-			 * last of this array, or something before this node.
-			 */
-			*result = ldns_radix_last_in_subtree_incl_self(node);
-			if (*result == NULL) {
-				*result = ldns_radix_prev(node);
-			}
-			return 0;
-		}
-		pos++;
-		if (!node->array[byte].edge) {
-			/**
-			 * No exact match. Find the previous in the array
-			 * from this index.
-			 */
-			*result = ldns_radix_prev_from_index(node, byte);
-			if (*result == NULL) {
-				ldns_radix_self_or_prev(node, result);
-			}
-			return 0;
-		}
-		if (node->array[byte].len != 0) {
-			/** Must match additional string. */
-			if (pos + node->array[byte].len > len) {
-				/** Additional string is longer than key. */
-				if (memcmp(&key[pos], node->array[byte].str,
-					len-pos) <= 0) {
-					/** Key is before this node. */
-					*result = ldns_radix_prev(
-						node->array[byte].edge);
-				} else {
-					/** Key is after additional string. */
-					*result = ldns_radix_last_in_subtree_incl_self(node->array[byte].edge);
-					if (*result == NULL) {
-						 *result = ldns_radix_prev(node->array[byte].edge);
-					}
-				}
-				return 0;
-			}
-			memcmp_res = memcmp(&key[pos], node->array[byte].str,
-				node->array[byte].len);
-			if (memcmp_res < 0) {
-				*result = ldns_radix_prev(
-					node->array[byte].edge);
-				return 0;
-			} else if (memcmp_res > 0) {
-				*result = ldns_radix_last_in_subtree_incl_self(node->array[byte].edge);
-				if (*result == NULL) {
-					 *result = ldns_radix_prev(node->array[byte].edge);
-				}
-				return 0;
-			}
-
-			pos += node->array[byte].len;
-		}
-		node = node->array[byte].edge;
-	}
-	if (node->data) {
-		/** Exact match. */
-		*result = node;
-		return 1;
-	}
-	/** There is a node which is an exact match, but has no element. */
-	*result = ldns_radix_prev(node);
-	return 0;
-}
-
-
-/**
- * Get the first element in the tree.
- *
- */
-ldns_radix_node_t*
-ldns_radix_first(ldns_radix_t* tree)
-{
-	ldns_radix_node_t* first = NULL;
-	if (!tree || !tree->root) {
-		return NULL;
-	}
-	first = tree->root;
-	if (first->data) {
-		return first;
-	}
-	return ldns_radix_next(first);
-}
-
-
-/**
- * Get the last element in the tree.
- *
- */
-ldns_radix_node_t*
-ldns_radix_last(ldns_radix_t* tree)
-{
-	if (!tree || !tree->root) {
-		return NULL;
-	}
-	return ldns_radix_last_in_subtree_incl_self(tree->root);
-}
-
-
-/**
- * Next element.
- *
- */
-ldns_radix_node_t*
-ldns_radix_next(ldns_radix_node_t* node)
-{
-	if (!node) {
-		return NULL;
-	}
-	if (node->len) {
-		/** Go down: most-left child is the next. */
-		ldns_radix_node_t* next = ldns_radix_next_in_subtree(node);
-		if (next) {
-			return next;
-		}
-	}
-	/** No elements in subtree, get to parent and go down next branch. */
-	while (node->parent) {
-		uint8_t index = node->parent_index;
-		node = node->parent;
-		index++;
-		for (; index < node->len; index++) {
-			if (node->array[index].edge) {
-				ldns_radix_node_t* next;
-				/** Node itself. */
-				if (node->array[index].edge->data) {
-					return node->array[index].edge;
-				}
-				/** Dive into subtree. */
-				next = ldns_radix_next_in_subtree(node);
-				if (next) {
-					return next;
-				}
-			}
-		}
-	}
-	return NULL;
-}
-
-
-/**
- * Previous element.
- *
- */
-ldns_radix_node_t*
-ldns_radix_prev(ldns_radix_node_t* node)
-{
-	if (!node) {
-		return NULL;
-	}
-
-	/** Get to parent and go down previous branch. */
-	while (node->parent) {
-		uint8_t index = node->parent_index;
-		ldns_radix_node_t* prev;
-		node = node->parent;
-		assert(node->len > 0);
-		prev = ldns_radix_prev_from_index(node, index);
-		if (prev) {
-			return prev;
-		}
-		if (node->data) {
-			return node;
-		}
-	}
-	return NULL;
-}
-
-
-/**
- * Print node.
- *
- */
-static void
-ldns_radix_node_print(FILE* fd, ldns_radix_node_t* node,
-	uint8_t i, uint8_t* str, radix_strlen_t len, unsigned d)
-{
-	uint8_t j;
-	if (!node) {
-		return;
-	}
-	for (j = 0; j < d; j++) {
-		fprintf(fd, "--");
-	}
-	if (str) {
-		radix_strlen_t l;
-		fprintf(fd, "| [%u+", (unsigned) i);
-		for (l=0; l < len; l++) {
-			fprintf(fd, "%c", (char) str[l]);
-		}
-		fprintf(fd, "]%u", (unsigned) len);
-	} else {
-		fprintf(fd, "| [%u]", (unsigned) i);
-	}
-
-	if (node->data) {
-		fprintf(fd, " %s", (char*) node->data);
-	}
-	fprintf(fd, "\n");
-
-	for (j = 0; j < node->len; j++) {
-		if (node->array[j].edge) {
-			ldns_radix_node_print(fd, node->array[j].edge, j,
-				node->array[j].str, node->array[j].len, d+1);
-		}
-	}
-	return;
-}
-
-
-/**
- * Print radix tree.
- *
- */
-void
-ldns_radix_printf(FILE* fd, ldns_radix_t* tree)
-{
-	if (!fd || !tree) {
-		return;
-	}
-	if (!tree->root) {
-		fprintf(fd, "; empty radix tree\n");
-		return;
-	}
-	ldns_radix_node_print(fd, tree->root, 0, NULL, 0, 0);
-	return;
-}
-
-
-/**
- * Join two radix trees.
- *
- */
-ldns_status
-ldns_radix_join(ldns_radix_t* tree1, ldns_radix_t* tree2)
-{
-	ldns_radix_node_t* cur_node, *next_node;
-	ldns_status status;
-	if (!tree2 || !tree2->root) {
-		return LDNS_STATUS_OK;
-	}
-	/** Add all elements from tree2 into tree1. */
-
-	cur_node = ldns_radix_first(tree2);
-	while (cur_node) {
-		status = LDNS_STATUS_NO_DATA;
-		/** Insert current node into tree1 */
-		if (cur_node->data) {
-			status = ldns_radix_insert(tree1, cur_node->key,
-				cur_node->klen, cur_node->data);
-			/** Exist errors may occur */
-			if (status != LDNS_STATUS_OK &&
-			    status != LDNS_STATUS_EXISTS_ERR) {
-				return status;
-			}
-		}
-		next_node = ldns_radix_next(cur_node);
-		if (status == LDNS_STATUS_OK) {
-			(void) ldns_radix_delete(tree2, cur_node->key,
-				cur_node->klen);
-		}
-		cur_node = next_node;
-	}
-
-	return LDNS_STATUS_OK;
-}
-
-
-/**
- * Split a radix tree intwo.
- *
- */
-ldns_status
-ldns_radix_split(ldns_radix_t* tree1, size_t num, ldns_radix_t** tree2)
-{
-	size_t count = 0;
-	ldns_radix_node_t* cur_node;
-	ldns_status status = LDNS_STATUS_OK;
-	if (!tree1 || !tree1->root || num == 0) {
-		return LDNS_STATUS_OK;
-	}
-	if (!tree2) {
-		return LDNS_STATUS_NULL;
-	}
-	if (!*tree2) {
-		*tree2 = ldns_radix_create();
-		if (!*tree2) {
-			return LDNS_STATUS_MEM_ERR;
-		}
-	}
-	cur_node = ldns_radix_first(tree1);
-	while (count < num && cur_node) {
-		if (cur_node->data) {
-			/** Delete current node from tree1. */
-			uint8_t* cur_key = cur_node->key;
-			radix_strlen_t cur_len = cur_node->klen;
-			void* cur_data = ldns_radix_delete(tree1, cur_key,
-				cur_len);
-			/** Insert current node into tree2/ */
-			if (!cur_data) {
-				return LDNS_STATUS_NO_DATA;
-			}
-			status = ldns_radix_insert(*tree2, cur_key, cur_len,
-				cur_data);
-			if (status != LDNS_STATUS_OK &&
-			    status != LDNS_STATUS_EXISTS_ERR) {
-				return status;
-			}
-/*
-			if (status == LDNS_STATUS_OK) {
-				cur_node->key = NULL;
-				cur_node->klen = 0;
-			}
-*/
-			/** Update count; get first element from tree1 again. */
-			count++;
-			cur_node = ldns_radix_first(tree1);
-		} else {
-			cur_node = ldns_radix_next(cur_node);
-		}
-	}
-	return LDNS_STATUS_OK;
-}
-
-
-/**
- * Call function for all nodes in the tree, such that leaf nodes are
- * called before parent nodes.
- *
- */
-void
-ldns_radix_traverse_postorder(ldns_radix_node_t* node,
-	void (*func)(ldns_radix_node_t*, void*), void* arg)
-{
-	uint8_t i;
-	if (!node) {
-		return;
-	}
-	for (i=0; i < node->len; i++) {
-		ldns_radix_traverse_postorder(node->array[i].edge,
-			func, arg);
-	}
-	/** Call user function */
-	(*func)(node, arg);
-	return;
-}
-
-
-/** Static helper functions */
-
-/**
- * Find a prefix of the key.
- * @param tree:   tree.
- * @param key:    key.
- * @param len:    length of key.
- * @param result: the longest prefix, the entry itself if *pos==len,
- *                otherwise an array entry.
- * @param pos:    position in string where next unmatched byte is.
- *                If *pos==len, an exact match is found.
- *                If *pos== 0, a "" match was found.
- * @return 0 (false) if no prefix found.
- *
- */
-static int
-ldns_radix_find_prefix(ldns_radix_t* tree, uint8_t* key,
-	radix_strlen_t len, ldns_radix_node_t** result, radix_strlen_t* respos)
-{
-	/** Start searching at the root node */
-	ldns_radix_node_t* n = tree->root;
-	radix_strlen_t pos = 0;
-	uint8_t byte;
-	*respos = 0;
-	*result = n;
-        if (!n) {
-		/** No root, no prefix found */
-		return 0;
-	}
-	/** For each node, look if we can make further progress */
-	while (n) {
-		if (pos == len) {
-			/** Exact match */
-			return 1;
-		}
-		byte = key[pos];
-		if (byte < n->offset) {
-			/** key < node */
-			return 1;
-		}
-		byte -= n->offset;
-		if (byte >= n->len) {
-			/** key > node */
-			return 1;
-		}
-		/** So far, the trie matches */
-		pos++;
-		if (n->array[byte].len != 0) {
-			/** Must match additional string */
-			if (pos + n->array[byte].len > len) {
-				return 1; /* no match at child node */
-			}
-			if (memcmp(&key[pos], n->array[byte].str,
-				n->array[byte].len) != 0) {
-				return 1; /* no match at child node */
-			}
-			pos += n->array[byte].len;
-		}
-		/** Continue searching prefix at this child node */
-		n = n->array[byte].edge;
-		if (!n) {
-			return 1;
-		}
-		/** Update the prefix node */
-		*respos = pos;
-		*result = n;
-	}
-	/** Done */
-	return 1;
-}
-
-
-/**
- * Make space in the node's array for another byte.
- * @param node: node.
- * @param byte: byte.
- * @return 1 if successful, 0 otherwise.
- *
- */
-static int
-ldns_radix_array_space(ldns_radix_node_t* node, uint8_t byte)
-{
-	/** Is there an array? */
-	if (!node->array) {
-		assert(node->capacity == 0);
-		/** No array, create new array */
-		node->array = LDNS_MALLOC(ldns_radix_array_t);
-		if (!node->array) {
-			return 0;
-		}
-		memset(&node->array[0], 0, sizeof(ldns_radix_array_t));
-		node->len = 1;
-		node->capacity = 1;
-		node->offset = byte;
-		return 1;
-	}
-	/** Array exist */
-	assert(node->array != NULL);
-	assert(node->capacity > 0);
-
-	if (node->len == 0) {
-		/** Unused array */
-		node->len = 1;
-		node->offset = byte;
-	} else if (byte < node->offset) {
-		/** Byte is below the offset */
-		uint8_t index;
-		uint16_t need = node->offset - byte;
-		/** Is there enough capacity? */
-		if (node->len + need > node->capacity) {
-			/** Not enough capacity, grow array */
-			if (!ldns_radix_array_grow(node,
-				(unsigned) (node->len + need))) {
-				return 0; /* failed to grow array */
-			}
-		}
-		/** Move items to the end */
-		memmove(&node->array[need], &node->array[0],
-			node->len*sizeof(ldns_radix_array_t));
-		/** Fix parent index */
-		for (index = 0; index < node->len; index++) {
-			if (node->array[index+need].edge) {
-				node->array[index+need].edge->parent_index =
-					index + need;
-			}
-		}
-		/** Zero the first */
-		memset(&node->array[0], 0, need*sizeof(ldns_radix_array_t));
-		node->len += need;
-		node->offset = byte;
-	} else if (byte - node->offset >= node->len) {
-		/** Byte does not fit in array */
-		uint16_t need = (byte - node->offset) - node->len + 1;
-		/** Is there enough capacity? */
-		if (node->len + need > node->capacity) {
-			/** Not enough capacity, grow array */
-			if (!ldns_radix_array_grow(node,
-				(unsigned) (node->len + need))) {
-				return 0; /* failed to grow array */
-			}
-		}
-		/** Zero the added items */
-		memset(&node->array[node->len], 0,
-			need*sizeof(ldns_radix_array_t));
-		node->len += need;
-	}
-	return 1;
-}
-
-
-/**
- * Grow the array.
- * @param node: node.
- * @param need: number of elements the array at least need to grow.
- *              Can't be bigger than 256.
- * @return: 0 if failed, 1 if was successful.
- *
- */
-static int
-ldns_radix_array_grow(ldns_radix_node_t* node, unsigned need)
-{
-	unsigned size = ((unsigned)node->capacity)*2;
-	ldns_radix_array_t* a = NULL;
-	if (need > size) {
-		size = need;
-	}
-	if (size > 256) {
-		size = 256;
-	}
-	a = LDNS_XMALLOC(ldns_radix_array_t, size);
-	if (!a) {
-		return 0;
-	}
-	assert(node->len <= node->capacity);
-	assert(node->capacity < size);
-	memcpy(&a[0], &node->array[0], node->len*sizeof(ldns_radix_array_t));
-	LDNS_FREE(node->array);
-	node->array = a;
-	node->capacity = size;
-	return 1;
-}
-
-
-/**
- * Create a prefix in the array string.
- * @param array: array.
- * @param key:   key.
- * @param pos:   start position in key.
- * @param len:   length of key.
- * @return 0 if failed, 1 if was successful.
- *
- */
-static int
-ldns_radix_str_create(ldns_radix_array_t* array, uint8_t* key,
-	radix_strlen_t pos, radix_strlen_t len)
-{
-	array->str = LDNS_XMALLOC(uint8_t, (len-pos));
-	if (!array->str) {
-		return 0;
-	}
-	memmove(array->str, key+pos, len-pos);
-	array->len = (len-pos);
-	return 1;
-}
-
-
-/**
- * Allocate remainder from prefixes for a split.
- * @param prefixlen:  length of prefix.
- * @param longer_str: the longer string.
- * @param longer_len: the longer string length.
- * @param split_str:  the split string.
- * @param split_len:  the split string length.
- * @return 0 if failed, 1 if successful.
- *
- */
-static int
-ldns_radix_prefix_remainder(radix_strlen_t prefix_len,
-	uint8_t* longer_str, radix_strlen_t longer_len,
-	uint8_t** split_str, radix_strlen_t* split_len)
-{
-	*split_len = longer_len - prefix_len;
-	*split_str = LDNS_XMALLOC(uint8_t, (*split_len));
-	if (!*split_str) {
-		return 0;
-	}
-	memmove(*split_str, longer_str+prefix_len, longer_len-prefix_len);
-	return 1;
-}
-
-
-/**
- * Create a split when two nodes have a shared prefix.
- * @param array: array.
- * @param key:   key.
- * @param pos:   start position in key.
- * @param len:   length of the key.
- * @param add:   node to be added.
- * @return 0 if failed, 1 if was successful.
- *
- */
-static int
-ldns_radix_array_split(ldns_radix_array_t* array, uint8_t* key,
-	radix_strlen_t pos, radix_strlen_t len, ldns_radix_node_t* add)
-{
-	uint8_t* str_to_add = key + pos;
-	radix_strlen_t strlen_to_add = len - pos;
-
-	if (ldns_radix_str_is_prefix(str_to_add, strlen_to_add,
-		array->str, array->len)) {
-		/** The string to add is a prefix of the existing string */
-		uint8_t* split_str = NULL, *dup_str = NULL;
-		radix_strlen_t split_len = 0;
-		/**
-		 * Example 5: 'ld'
-		 * | [0]
-		 * --| [d+ns] dns
-		 * --| [e+dns] edns
-		 * --| [l+d] ld
-		 * ----| [n+s] ldns
-		 **/
-		assert(strlen_to_add < array->len);
-		/** Store the remainder in the split string */
-		if (array->len - strlen_to_add > 1) {
-			if (!ldns_radix_prefix_remainder(strlen_to_add+1,
-				array->str, array->len, &split_str,
-				&split_len)) {
-				return 0;
-			}
-		}
-		/** Duplicate the string to add */
-		if (strlen_to_add != 0) {
-			dup_str = LDNS_XMALLOC(uint8_t, strlen_to_add);
-			if (!dup_str) {
-				LDNS_FREE(split_str);
-				return 0;
-			}
-			memcpy(dup_str, str_to_add, strlen_to_add);
-		}
-		/** Make space in array for the new node */
-		if (!ldns_radix_array_space(add,
-			array->str[strlen_to_add])) {
-			LDNS_FREE(split_str);
-			LDNS_FREE(dup_str);
-			return 0;
-		}
-		/**
-		 * The added node should go direct under the existing parent.
-		 * The existing node should go under the added node.
-		 */
-		add->parent = array->edge->parent;
-		add->parent_index = array->edge->parent_index;
-		add->array[0].edge = array->edge;
-		add->array[0].str = split_str;
-		add->array[0].len = split_len;
-		array->edge->parent = add;
-		array->edge->parent_index = 0;
-		LDNS_FREE(array->str);
-		array->edge = add;
-		array->str = dup_str;
-		array->len = strlen_to_add;
-	} else if (ldns_radix_str_is_prefix(array->str, array->len,
-		str_to_add, strlen_to_add)) {
-		/** The existing string is a prefix of the string to add */
-		/**
-		 * Example 6: 'dns-ng'
-		 * | [0]
-		 * --| [d+ns] dns
-		 * ----| [-+ng] dns-ng
-		 * --| [e+dns] edns
-		 * --| [l+d] ld
-		 * ----| [n+s] ldns
-		 **/
-		uint8_t* split_str = NULL;
-		radix_strlen_t split_len = 0;
-		assert(array->len < strlen_to_add);
-		if (strlen_to_add - array->len > 1) {
-			if (!ldns_radix_prefix_remainder(array->len+1,
-				str_to_add, strlen_to_add, &split_str,
-				&split_len)) {
-				return 0;
-			}
-		}
-		/** Make space in array for the new node */
-		if (!ldns_radix_array_space(array->edge,
-			str_to_add[array->len])) {
-			LDNS_FREE(split_str);
-			return 0;
-		}
-		/**
-		 * The added node should go direct under the existing node.
-		 */
-		add->parent = array->edge;
-		add->parent_index = str_to_add[array->len] -
-							array->edge->offset;
-		array->edge->array[add->parent_index].edge = add;
-		array->edge->array[add->parent_index].str = split_str;
-		array->edge->array[add->parent_index].len = split_len;
-	} else {
-		/** Create a new split node. */
-		/**
-		 * Example 7: 'dndns'
-		 * | [0]
-		 * --| [d+n]
-		 * ----| [d+ns] dndns
-		 * ----| [s] dns
-		 * ------| [-+ng] dns-ng
-		 * --| [e+dns] edns
-		 * --| [l+d] ld
-		 * ----| [n+s] ldns
-		 **/
-		ldns_radix_node_t* common = NULL;
-		uint8_t* common_str = NULL, *s1 = NULL, *s2 = NULL;
-		radix_strlen_t common_len = 0, l1 = 0, l2 = 0;
-		common_len = ldns_radix_str_common(array->str, array->len,
-			str_to_add, strlen_to_add);
-		assert(common_len < array->len);
-		assert(common_len < strlen_to_add);
-		/** Create the new common node. */
-		common = ldns_radix_new_node(NULL, (uint8_t*)"", 0);
-		if (!common) {
-			return 0;
-		}
-		if (array->len - common_len > 1) {
-			if (!ldns_radix_prefix_remainder(common_len+1,
-				array->str, array->len, &s1, &l1)) {
-				return 0;
-			}
-		}
-		if (strlen_to_add - common_len > 1) {
-			if (!ldns_radix_prefix_remainder(common_len+1,
-				str_to_add, strlen_to_add, &s2, &l2)) {
-				return 0;
-			}
-		}
-		/** Create the shared prefix. */
-		if (common_len > 0) {
-			common_str = LDNS_XMALLOC(uint8_t, common_len);
-			if (!common_str) {
-				LDNS_FREE(common);
-				LDNS_FREE(s1);
-				LDNS_FREE(s2);
-				return 0;
-			}
-			memcpy(common_str, str_to_add, common_len);
-		}
-		/** Make space in the common node array. */
-		if (!ldns_radix_array_space(common, array->str[common_len]) ||
-		    !ldns_radix_array_space(common, str_to_add[common_len])) {
-			LDNS_FREE(common->array);
-			LDNS_FREE(common);
-			LDNS_FREE(common_str);
-			LDNS_FREE(s1);
-			LDNS_FREE(s2);
-			return 0;
-		}
-		/**
-		 * The common node should go direct under the parent node.
-		 * The added and existing nodes go under the common node.
-		 */
-		common->parent = array->edge->parent;
-		common->parent_index = array->edge->parent_index;
-		array->edge->parent = common;
-		array->edge->parent_index = array->str[common_len] -
-								common->offset;
-		add->parent = common;
-		add->parent_index = str_to_add[common_len] - common->offset;
-		common->array[array->edge->parent_index].edge = array->edge;
-		common->array[array->edge->parent_index].str = s1;
-		common->array[array->edge->parent_index].len = l1;
-		common->array[add->parent_index].edge = add;
-		common->array[add->parent_index].str = s2;
-		common->array[add->parent_index].len = l2;
-		LDNS_FREE(array->str);
-		array->edge = common;
-		array->str = common_str;
-		array->len = common_len;
-	}
-	return 1;
-}
-
-
-/**
- * Check if one string prefix of other string.
- * @param str1: one string.
- * @param len1: one string length.
- * @param str2: other string.
- * @param len2: other string length.
- * @return 1 if prefix, 0 otherwise.
- *
- */
-static int
-ldns_radix_str_is_prefix(uint8_t* str1, radix_strlen_t len1,
-	uint8_t* str2, radix_strlen_t len2)
-{
-	if (len1 == 0) {
-		return 1; /* empty prefix is also a prefix */
-	}
-	if (len1 > len2) {
-		return 0; /* len1 is longer so str1 cannot be a prefix */
-	}
-	return (memcmp(str1, str2, len1) == 0);
-}
-
-
-/**
- * Return the number of bytes in common for the two strings.
- * @param str1: one string.
- * @param len1: one string length.
- * @param str2: other string.
- * @param len2: other string length.
- * @return length of substring that the two strings have in common.
- *
- */
-static radix_strlen_t
-ldns_radix_str_common(uint8_t* str1, radix_strlen_t len1,
-	uint8_t* str2, radix_strlen_t len2)
-{
-	radix_strlen_t i, max = (len1<len2)?len1:len2;
-	for (i=0; i<max; i++) {
-		if (str1[i] != str2[i]) {
-			return i;
-		}
-	}
-	return max;
-}
-
-
-/**
- * Find the next element in the subtree of this node.
- * @param node: node.
- * @return: node with next element.
- *
- */
-static ldns_radix_node_t*
-ldns_radix_next_in_subtree(ldns_radix_node_t* node)
-{
-	uint16_t i;
-	ldns_radix_node_t* next;
-	/** Try every subnode. */
-	for (i = 0; i < node->len; i++) {
-		if (node->array[i].edge) {
-			/** Node itself. */
-			if (node->array[i].edge->data) {
-				return node->array[i].edge;
-			}
-			/** Dive into subtree. */
-			next = ldns_radix_next_in_subtree(node->array[i].edge);
-			if (next) {
-				return next;
-			}
-		}
-	}
-	return NULL;
-}
-
-
-/**
- * Find the previous element in the array of this node, from index.
- * @param node: node.
- * @param index: index.
- * @return previous node from index.
- *
- */
-static ldns_radix_node_t*
-ldns_radix_prev_from_index(ldns_radix_node_t* node, uint8_t index)
-{
-	uint8_t i = index;
-	while (i > 0) {
-		i--;
-		if (node->array[i].edge) {
-			ldns_radix_node_t* prev =
-				ldns_radix_last_in_subtree_incl_self(node);
-			if (prev) {
-				return prev;
-			}
-		}
-	}
-	return NULL;
-}
-
-
-/**
- * Find last node in subtree, or this node (if have data).
- * @param node: node.
- * @return last node in subtree, or this node, or NULL.
- *
- */
-static ldns_radix_node_t*
-ldns_radix_last_in_subtree_incl_self(ldns_radix_node_t* node)
-{
-	ldns_radix_node_t* last = ldns_radix_last_in_subtree(node);
-	if (last) {
-		return last;
-	} else if (node->data) {
-		return node;
-	}
-	return NULL;
-}
-
-
-/**
- * Find last node in subtree.
- * @param node: node.
- * @return last node in subtree.
- *
- */
-static ldns_radix_node_t*
-ldns_radix_last_in_subtree(ldns_radix_node_t* node)
-{
-	int i;
-	/** Look for the most right leaf node. */
-	for (i=(int)(node->len)-1; i >= 0; i--) {
-		if (node->array[i].edge) {
-			/** Keep looking for the most right leaf node. */
-			if (node->array[i].edge->len > 0) {
-				ldns_radix_node_t* last =
-					ldns_radix_last_in_subtree(
-					node->array[i].edge);
-				if (last) {
-					return last;
-				}
-			}
-			/** Could this be the most right leaf node? */
-			if (node->array[i].edge->data) {
-				return node->array[i].edge;
-			}
-		}
-	}
-	return NULL;
-}
-
-
-/**
- * Fix tree after deleting element.
- * @param tree: tree.
- * @param node: node with deleted element.
- *
- */
-static void
-ldns_radix_del_fix(ldns_radix_t* tree, ldns_radix_node_t* node)
-{
-	while (node) {
-		if (node->data) {
-			/** Thou should not delete nodes with data attached. */
-			return;
-		} else if (node->len == 1 && node->parent) {
-			/** Node with one child is fold back into. */
-			ldns_radix_cleanup_onechild(node);
-			return;
-		} else if (node->len == 0) {
-			/** Leaf node. */
-			ldns_radix_node_t* parent = node->parent;
-			if (!parent) {
-				/** The root is a leaf node. */
-				ldns_radix_node_free(node, NULL);
-				tree->root = NULL;
-				return;
-			}
-			/** Cleanup leaf node and continue with parent. */
-			ldns_radix_cleanup_leaf(node);
-			node = parent;
-		} else {
-			/**
-			 * Node cannot be deleted, because it has edge nodes
-			 * and no parent to fix up to.
-			 */
-			return;
-		}
-	}
-	/** Not reached. */
-	return;
-}
-
-
-/**
- * Clean up a node with one child.
- * @param node: node with one child.
- *
- */
-static void
-ldns_radix_cleanup_onechild(ldns_radix_node_t* node)
-{
-	uint8_t* join_str;
-	radix_strlen_t join_len;
-	uint8_t parent_index = node->parent_index;
-	ldns_radix_node_t* child = node->array[0].edge;
-	ldns_radix_node_t* parent = node->parent;
-
-	/** Node has one child, merge the child node into the parent node. */
-	assert(parent_index < parent->len);
-	join_len = parent->array[parent_index].len + node->array[0].len + 1;
-
-	join_str = LDNS_XMALLOC(uint8_t, join_len);
-	if (!join_str) {
-		/**
-		 * Cleanup failed due to out of memory.
-		 * This tree is now inefficient, with the empty node still
-		 * existing, but it is still valid.
-		 */
-		return;
-	}
-
-	memcpy(join_str, parent->array[parent_index].str,
-		parent->array[parent_index].len);
-	join_str[parent->array[parent_index].len] = child->parent_index +
-		node->offset;
-	memmove(join_str + parent->array[parent_index].len+1,
-		node->array[0].str, node->array[0].len);
-
-	LDNS_FREE(parent->array[parent_index].str);
-	parent->array[parent_index].str = join_str;
-	parent->array[parent_index].len = join_len;
-	parent->array[parent_index].edge = child;
-	child->parent = parent;
-	child->parent_index = parent_index;
-	ldns_radix_node_free(node, NULL);
-	return;
-}
-
-
-/**
- * Clean up a leaf node.
- * @param node: leaf node.
- *
- */
-static void
-ldns_radix_cleanup_leaf(ldns_radix_node_t* node)
-{
-	uint8_t parent_index = node->parent_index;
-	ldns_radix_node_t* parent = node->parent;
-	/** Delete lead node and fix parent array. */
-	assert(parent_index < parent->len);
-	ldns_radix_node_free(node, NULL);
-	LDNS_FREE(parent->array[parent_index].str);
-	parent->array[parent_index].str = NULL;
-	parent->array[parent_index].len = 0;
-	parent->array[parent_index].edge = NULL;
-	/** Fix array in parent. */
-	if (parent->len == 1) {
-		ldns_radix_node_array_free(parent);
-	} else if (parent_index == 0) {
-		ldns_radix_node_array_free_front(parent);
-	} else {
-		ldns_radix_node_array_free_end(parent);
-	}
-	return;
-}
-
-
-/**
- * Free a radix node.
- * @param node: node.
- * @param arg: user argument.
- *
- */
-static void
-ldns_radix_node_free(ldns_radix_node_t* node, void* arg)
-{
-	uint16_t i;
-	(void) arg;
-	if (!node) {
-		return;
-	}
-	for (i=0; i < node->len; i++) {
-		LDNS_FREE(node->array[i].str);
-	}
-	node->key = NULL;
-	node->klen = 0;
-	LDNS_FREE(node->array);
-	LDNS_FREE(node);
-	return;
-}
-
-
-/**
- * Free select edge array.
- * @param node: node.
- *
- */
-static void
-ldns_radix_node_array_free(ldns_radix_node_t* node)
-{
-	node->offset = 0;
-	node->len = 0;
-	LDNS_FREE(node->array);
-	node->array = NULL;
-	node->capacity = 0;
-	return;
-}
-
-
-/**
- * Free front of select edge array.
- * @param node: node.
- *
- */
-static void
-ldns_radix_node_array_free_front(ldns_radix_node_t* node)
-{
-	uint16_t i, n = 0;
-	/** Remove until a non NULL entry. */
-   	while (n < node->len && node->array[n].edge == NULL) {
-		n++;
-	}
-	if (n == 0) {
-		return;
-	}
-	if (n == node->len) {
-		ldns_radix_node_array_free(node);
-		return;
-	}
-	assert(n < node->len);
-	assert((int) n <= (255 - (int) node->offset));
-	memmove(&node->array[0], &node->array[n],
-		(node->len - n)*sizeof(ldns_radix_array_t));
-	node->offset += n;
-	node->len -= n;
-	for (i=0; i < node->len; i++) {
-		if (node->array[i].edge) {
-			node->array[i].edge->parent_index = i;
-		}
-	}
-	ldns_radix_array_reduce(node);
-	return;
-}
-
-
-/**
- * Free front of select edge array.
- * @param node: node.
- *
- */
-static void
-ldns_radix_node_array_free_end(ldns_radix_node_t* node)
-{
-	uint16_t n = 0;
-	/** Shorten array. */
-	while (n < node->len && node->array[node->len-1-n].edge == NULL) {
-		n++;
-	}
-	if (n == 0) {
-		return;
-	}
-	if (n == node->len) {
-		ldns_radix_node_array_free(node);
-		return;
-	}
-	assert(n < node->len);
-	node->len -= n;
-	ldns_radix_array_reduce(node);
-	return;
-}
-
-
-/**
- * Reduce the capacity of the array if needed.
- * @param node: node.
- *
- */
-static void
-ldns_radix_array_reduce(ldns_radix_node_t* node)
-{
-	if (node->len <= node->capacity/2 && node->len != node->capacity) {
-		ldns_radix_array_t* a = LDNS_XMALLOC(ldns_radix_array_t,
-								node->len);
-		if (!a) {
-			return;
-		}
-		memcpy(a, node->array, sizeof(ldns_radix_array_t)*node->len);
-		LDNS_FREE(node->array);
-		node->array = a;
-		node->capacity = node->len;
-	}
-	return;
-}
-
-
-/**
- * Return this element if it exists, the previous otherwise.
- * @param node: from this node.
- * @param result: result node.
- *
- */
-static void
-ldns_radix_self_or_prev(ldns_radix_node_t* node, ldns_radix_node_t** result)
-{
-	if (node->data) {
-		*result = node;
-	} else {
-		*result = ldns_radix_prev(node);
-	}
-	return;
-}
diff --git a/src/ldns/rbtree.c b/src/ldns/rbtree.c
deleted file mode 100644
index b89dff7..0000000
--- a/src/ldns/rbtree.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * rbtree.c -- generic red black tree
- *
- * Taken from Unbound, modified for ldns
- *
- * Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
- * 
- * This software is open source.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 
- * Neither the name of the NLNET LABS nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * \file
- * Implementation of a redblack tree.
- */
-
-#include <ldns/config.h>
-#include <ldns/rbtree.h>
-#include <ldns/util.h>
-#include <stdlib.h>
-
-/** Node colour black */
-#define	BLACK	0
-/** Node colour red */
-#define	RED	1
-
-/** the NULL node, global alloc */
-ldns_rbnode_t	ldns_rbtree_null_node = {
-	LDNS_RBTREE_NULL,	/* Parent.  */
-	LDNS_RBTREE_NULL,	/* Left.  */
-	LDNS_RBTREE_NULL,	/* Right.  */
-	NULL,			/* Key.  */
-	NULL,               /* Data. */
-	BLACK		     /* Color.  */
-};
-
-/** rotate subtree left (to preserve redblack property) */
-static void ldns_rbtree_rotate_left(ldns_rbtree_t *rbtree, ldns_rbnode_t *node);
-/** rotate subtree right (to preserve redblack property) */
-static void ldns_rbtree_rotate_right(ldns_rbtree_t *rbtree, ldns_rbnode_t *node);
-/** Fixup node colours when insert happened */
-static void ldns_rbtree_insert_fixup(ldns_rbtree_t *rbtree, ldns_rbnode_t *node);
-/** Fixup node colours when delete happened */
-static void ldns_rbtree_delete_fixup(ldns_rbtree_t* rbtree, ldns_rbnode_t* child, ldns_rbnode_t* child_parent);
-
-/*
- * Creates a new red black tree, intializes and returns a pointer to it.
- *
- * Return NULL on failure.
- *
- */
-ldns_rbtree_t *
-ldns_rbtree_create (int (*cmpf)(const void *, const void *))
-{
-	ldns_rbtree_t *rbtree;
-
-	/* Allocate memory for it */
-	rbtree = (ldns_rbtree_t *) LDNS_MALLOC(ldns_rbtree_t);
-	if (!rbtree) {
-		return NULL;
-	}
-
-	/* Initialize it */
-	ldns_rbtree_init(rbtree, cmpf);
-
-	return rbtree;
-}
-
-void 
-ldns_rbtree_init(ldns_rbtree_t *rbtree, int (*cmpf)(const void *, const void *))
-{
-	/* Initialize it */
-	rbtree->root = LDNS_RBTREE_NULL;
-	rbtree->count = 0;
-	rbtree->cmp = cmpf;
-}
-
-void 
-ldns_rbtree_free(ldns_rbtree_t *rbtree)
-{
-	LDNS_FREE(rbtree);
-}
-
-/*
- * Rotates the node to the left.
- *
- */
-static void
-ldns_rbtree_rotate_left(ldns_rbtree_t *rbtree, ldns_rbnode_t *node)
-{
-	ldns_rbnode_t *right = node->right;
-	node->right = right->left;
-	if (right->left != LDNS_RBTREE_NULL)
-		right->left->parent = node;
-
-	right->parent = node->parent;
-
-	if (node->parent != LDNS_RBTREE_NULL) {
-		if (node == node->parent->left) {
-			node->parent->left = right;
-		} else  {
-			node->parent->right = right;
-		}
-	} else {
-		rbtree->root = right;
-	}
-	right->left = node;
-	node->parent = right;
-}
-
-/*
- * Rotates the node to the right.
- *
- */
-static void
-ldns_rbtree_rotate_right(ldns_rbtree_t *rbtree, ldns_rbnode_t *node)
-{
-	ldns_rbnode_t *left = node->left;
-	node->left = left->right;
-	if (left->right != LDNS_RBTREE_NULL)
-		left->right->parent = node;
-
-	left->parent = node->parent;
-
-	if (node->parent != LDNS_RBTREE_NULL) {
-		if (node == node->parent->right) {
-			node->parent->right = left;
-		} else  {
-			node->parent->left = left;
-		}
-	} else {
-		rbtree->root = left;
-	}
-	left->right = node;
-	node->parent = left;
-}
-
-static void
-ldns_rbtree_insert_fixup(ldns_rbtree_t *rbtree, ldns_rbnode_t *node)
-{
-	ldns_rbnode_t	*uncle;
-
-	/* While not at the root and need fixing... */
-	while (node != rbtree->root && node->parent->color == RED) {
-		/* If our parent is left child of our grandparent... */
-		if (node->parent == node->parent->parent->left) {
-			uncle = node->parent->parent->right;
-
-			/* If our uncle is red... */
-			if (uncle->color == RED) {
-				/* Paint the parent and the uncle black... */
-				node->parent->color = BLACK;
-				uncle->color = BLACK;
-
-				/* And the grandparent red... */
-				node->parent->parent->color = RED;
-
-				/* And continue fixing the grandparent */
-				node = node->parent->parent;
-			} else {				/* Our uncle is black... */
-				/* Are we the right child? */
-				if (node == node->parent->right) {
-					node = node->parent;
-					ldns_rbtree_rotate_left(rbtree, node);
-				}
-				/* Now we're the left child, repaint and rotate... */
-				node->parent->color = BLACK;
-				node->parent->parent->color = RED;
-				ldns_rbtree_rotate_right(rbtree, node->parent->parent);
-			}
-		} else {
-			uncle = node->parent->parent->left;
-
-			/* If our uncle is red... */
-			if (uncle->color == RED) {
-				/* Paint the parent and the uncle black... */
-				node->parent->color = BLACK;
-				uncle->color = BLACK;
-
-				/* And the grandparent red... */
-				node->parent->parent->color = RED;
-
-				/* And continue fixing the grandparent */
-				node = node->parent->parent;
-			} else {				/* Our uncle is black... */
-				/* Are we the right child? */
-				if (node == node->parent->left) {
-					node = node->parent;
-					ldns_rbtree_rotate_right(rbtree, node);
-				}
-				/* Now we're the right child, repaint and rotate... */
-				node->parent->color = BLACK;
-				node->parent->parent->color = RED;
-				ldns_rbtree_rotate_left(rbtree, node->parent->parent);
-			}
-		}
-	}
-	rbtree->root->color = BLACK;
-}
-
-void
-ldns_rbtree_insert_vref(ldns_rbnode_t *data, void *rbtree)
-{
-	(void) ldns_rbtree_insert((ldns_rbtree_t *) rbtree,
-						 data);
-}
-
-/*
- * Inserts a node into a red black tree.
- *
- * Returns NULL on failure or the pointer to the newly added node
- * otherwise.
- */
-ldns_rbnode_t *
-ldns_rbtree_insert (ldns_rbtree_t *rbtree, ldns_rbnode_t *data)
-{
-	/* XXX Not necessary, but keeps compiler quiet... */
-	int r = 0;
-
-	/* We start at the root of the tree */
-	ldns_rbnode_t	*node = rbtree->root;
-	ldns_rbnode_t	*parent = LDNS_RBTREE_NULL;
-
-	/* Lets find the new parent... */
-	while (node != LDNS_RBTREE_NULL) {
-		/* Compare two keys, do we have a duplicate? */
-		if ((r = rbtree->cmp(data->key, node->key)) == 0) {
-			return NULL;
-		}
-		parent = node;
-
-		if (r < 0) {
-			node = node->left;
-		} else {
-			node = node->right;
-		}
-	}
-
-	/* Initialize the new node */
-	data->parent = parent;
-	data->left = data->right = LDNS_RBTREE_NULL;
-	data->color = RED;
-	rbtree->count++;
-
-	/* Insert it into the tree... */
-	if (parent != LDNS_RBTREE_NULL) {
-		if (r < 0) {
-			parent->left = data;
-		} else {
-			parent->right = data;
-		}
-	} else {
-		rbtree->root = data;
-	}
-
-	/* Fix up the red-black properties... */
-	ldns_rbtree_insert_fixup(rbtree, data);
-
-	return data;
-}
-
-/*
- * Searches the red black tree, returns the data if key is found or NULL otherwise.
- *
- */
-ldns_rbnode_t *
-ldns_rbtree_search (ldns_rbtree_t *rbtree, const void *key)
-{
-	ldns_rbnode_t *node;
-
-	if (ldns_rbtree_find_less_equal(rbtree, key, &node)) {
-		return node;
-	} else {
-		return NULL;
-	}
-}
-
-/** helpers for delete: swap node colours */
-static void swap_int8(uint8_t* x, uint8_t* y) 
-{ 
-	uint8_t t = *x; *x = *y; *y = t; 
-}
-
-/** helpers for delete: swap node pointers */
-static void swap_np(ldns_rbnode_t** x, ldns_rbnode_t** y) 
-{
-	ldns_rbnode_t* t = *x; *x = *y; *y = t; 
-}
-
-/** Update parent pointers of child trees of 'parent' */
-static void change_parent_ptr(ldns_rbtree_t* rbtree, ldns_rbnode_t* parent, ldns_rbnode_t* old, ldns_rbnode_t* new)
-{
-	if(parent == LDNS_RBTREE_NULL)
-	{
-		if(rbtree->root == old) rbtree->root = new;
-		return;
-	}
-	if(parent->left == old) parent->left = new;
-	if(parent->right == old) parent->right = new;
-}
-/** Update parent pointer of a node 'child' */
-static void change_child_ptr(ldns_rbnode_t* child, ldns_rbnode_t* old, ldns_rbnode_t* new)
-{
-	if(child == LDNS_RBTREE_NULL) return;
-	if(child->parent == old) child->parent = new;
-}
-
-ldns_rbnode_t* 
-ldns_rbtree_delete(ldns_rbtree_t *rbtree, const void *key)
-{
-	ldns_rbnode_t *to_delete;
-	ldns_rbnode_t *child;
-	if((to_delete = ldns_rbtree_search(rbtree, key)) == 0) return 0;
-	rbtree->count--;
-
-	/* make sure we have at most one non-leaf child */
-	if(to_delete->left != LDNS_RBTREE_NULL &&
-	   to_delete->right != LDNS_RBTREE_NULL)
-	{
-		/* swap with smallest from right subtree (or largest from left) */
-		ldns_rbnode_t *smright = to_delete->right;
-		while(smright->left != LDNS_RBTREE_NULL)
-			smright = smright->left;
-		/* swap the smright and to_delete elements in the tree,
-		 * but the ldns_rbnode_t is first part of user data struct
-		 * so cannot just swap the keys and data pointers. Instead
-		 * readjust the pointers left,right,parent */
-
-		/* swap colors - colors are tied to the position in the tree */
-		swap_int8(&to_delete->color, &smright->color);
-
-		/* swap child pointers in parents of smright/to_delete */
-		change_parent_ptr(rbtree, to_delete->parent, to_delete, smright);
-		if(to_delete->right != smright)
-			change_parent_ptr(rbtree, smright->parent, smright, to_delete);
-
-		/* swap parent pointers in children of smright/to_delete */
-		change_child_ptr(smright->left, smright, to_delete);
-		change_child_ptr(smright->left, smright, to_delete);
-		change_child_ptr(smright->right, smright, to_delete);
-		change_child_ptr(smright->right, smright, to_delete);
-		change_child_ptr(to_delete->left, to_delete, smright);
-		if(to_delete->right != smright)
-			change_child_ptr(to_delete->right, to_delete, smright);
-		if(to_delete->right == smright)
-		{
-			/* set up so after swap they work */
-			to_delete->right = to_delete;
-			smright->parent = smright;
-		}
-
-		/* swap pointers in to_delete/smright nodes */
-		swap_np(&to_delete->parent, &smright->parent);
-		swap_np(&to_delete->left, &smright->left);
-		swap_np(&to_delete->right, &smright->right);
-
-		/* now delete to_delete (which is at the location where the smright previously was) */
-	}
-
-	if(to_delete->left != LDNS_RBTREE_NULL) child = to_delete->left;
-	else child = to_delete->right;
-
-	/* unlink to_delete from the tree, replace to_delete with child */
-	change_parent_ptr(rbtree, to_delete->parent, to_delete, child);
-	change_child_ptr(child, to_delete, to_delete->parent);
-
-	if(to_delete->color == RED)
-	{
-		/* if node is red then the child (black) can be swapped in */
-	}
-	else if(child->color == RED)
-	{
-		/* change child to BLACK, removing a RED node is no problem */
-		if(child!=LDNS_RBTREE_NULL) child->color = BLACK;
-	}
-	else ldns_rbtree_delete_fixup(rbtree, child, to_delete->parent);
-
-	/* unlink completely */
-	to_delete->parent = LDNS_RBTREE_NULL;
-	to_delete->left = LDNS_RBTREE_NULL;
-	to_delete->right = LDNS_RBTREE_NULL;
-	to_delete->color = BLACK;
-	return to_delete;
-}
-
-static void ldns_rbtree_delete_fixup(ldns_rbtree_t* rbtree, ldns_rbnode_t* child, ldns_rbnode_t* child_parent)
-{
-	ldns_rbnode_t* sibling;
-	int go_up = 1;
-
-	/* determine sibling to the node that is one-black short */
-	if(child_parent->right == child) sibling = child_parent->left;
-	else sibling = child_parent->right;
-
-	while(go_up)
-	{
-		if(child_parent == LDNS_RBTREE_NULL)
-		{
-			/* removed parent==black from root, every path, so ok */
-			return;
-		}
-
-		if(sibling->color == RED)
-		{	/* rotate to get a black sibling */
-			child_parent->color = RED;
-			sibling->color = BLACK;
-			if(child_parent->right == child)
-				ldns_rbtree_rotate_right(rbtree, child_parent);
-			else	ldns_rbtree_rotate_left(rbtree, child_parent);
-			/* new sibling after rotation */
-			if(child_parent->right == child) sibling = child_parent->left;
-			else sibling = child_parent->right;
-		}
-
-		if(child_parent->color == BLACK 
-			&& sibling->color == BLACK
-			&& sibling->left->color == BLACK
-			&& sibling->right->color == BLACK)
-		{	/* fixup local with recolor of sibling */
-			if(sibling != LDNS_RBTREE_NULL)
-				sibling->color = RED;
-
-			child = child_parent;
-			child_parent = child_parent->parent;
-			/* prepare to go up, new sibling */
-			if(child_parent->right == child) sibling = child_parent->left;
-			else sibling = child_parent->right;
-		}
-		else go_up = 0;
-	}
-
-	if(child_parent->color == RED
-		&& sibling->color == BLACK
-		&& sibling->left->color == BLACK
-		&& sibling->right->color == BLACK) 
-	{
-		/* move red to sibling to rebalance */
-		if(sibling != LDNS_RBTREE_NULL)
-			sibling->color = RED;
-		child_parent->color = BLACK;
-		return;
-	}
-
-	/* get a new sibling, by rotating at sibling. See which child
-	   of sibling is red */
-	if(child_parent->right == child
-		&& sibling->color == BLACK
-		&& sibling->right->color == RED
-		&& sibling->left->color == BLACK)
-	{
-		sibling->color = RED;
-		sibling->right->color = BLACK;
-		ldns_rbtree_rotate_left(rbtree, sibling);
-		/* new sibling after rotation */
-		if(child_parent->right == child) sibling = child_parent->left;
-		else sibling = child_parent->right;
-	}
-	else if(child_parent->left == child
-		&& sibling->color == BLACK
-		&& sibling->left->color == RED
-		&& sibling->right->color == BLACK)
-	{
-		sibling->color = RED;
-		sibling->left->color = BLACK;
-		ldns_rbtree_rotate_right(rbtree, sibling);
-		/* new sibling after rotation */
-		if(child_parent->right == child) sibling = child_parent->left;
-		else sibling = child_parent->right;
-	}
-
-	/* now we have a black sibling with a red child. rotate and exchange colors. */
-	sibling->color = child_parent->color;
-	child_parent->color = BLACK;
-	if(child_parent->right == child)
-	{
-		sibling->left->color = BLACK;
-		ldns_rbtree_rotate_right(rbtree, child_parent);
-	}
-	else
-	{
-		sibling->right->color = BLACK;
-		ldns_rbtree_rotate_left(rbtree, child_parent);
-	}
-}
-
-int
-ldns_rbtree_find_less_equal(ldns_rbtree_t *rbtree, const void *key, ldns_rbnode_t **result)
-{
-	int r;
-	ldns_rbnode_t *node;
-
-	/* We start at root... */
-	node = rbtree->root;
-
-	*result = NULL;
-
-	/* While there are children... */
-	while (node != LDNS_RBTREE_NULL) {
-		r = rbtree->cmp(key, node->key);
-		if (r == 0) {
-			/* Exact match */
-			*result = node;
-			return 1;
-		} 
-		if (r < 0) {
-			node = node->left;
-		} else {
-			/* Temporary match */
-			*result = node;
-			node = node->right;
-		}
-	}
-	return 0;
-}
-
-/*
- * Finds the first element in the red black tree
- *
- */
-ldns_rbnode_t *
-ldns_rbtree_first (ldns_rbtree_t *rbtree)
-{
-	ldns_rbnode_t *node = rbtree->root;
-
-	if (rbtree->root != LDNS_RBTREE_NULL) {
-		for (node = rbtree->root; node->left != LDNS_RBTREE_NULL; node = node->left);
-	}
-	return node;
-}
-
-ldns_rbnode_t *
-ldns_rbtree_last (ldns_rbtree_t *rbtree)
-{
-	ldns_rbnode_t *node = rbtree->root;
-
-	if (rbtree->root != LDNS_RBTREE_NULL) {
-		for (node = rbtree->root; node->right != LDNS_RBTREE_NULL; node = node->right);
-	}
-	return node;
-}
-
-/*
- * Returns the next node...
- *
- */
-ldns_rbnode_t *
-ldns_rbtree_next (ldns_rbnode_t *node)
-{
-	ldns_rbnode_t *parent;
-
-	if (node->right != LDNS_RBTREE_NULL) {
-		/* One right, then keep on going left... */
-		for (node = node->right;
-			node->left != LDNS_RBTREE_NULL;
-			node = node->left);
-	} else {
-		parent = node->parent;
-		while (parent != LDNS_RBTREE_NULL && node == parent->right) {
-			node = parent;
-			parent = parent->parent;
-		}
-		node = parent;
-	}
-	return node;
-}
-
-ldns_rbnode_t *
-ldns_rbtree_previous(ldns_rbnode_t *node)
-{
-	ldns_rbnode_t *parent;
-
-	if (node->left != LDNS_RBTREE_NULL) {
-		/* One left, then keep on going right... */
-		for (node = node->left;
-			node->right != LDNS_RBTREE_NULL;
-			node = node->right);
-	} else {
-		parent = node->parent;
-		while (parent != LDNS_RBTREE_NULL && node == parent->left) {
-			node = parent;
-			parent = parent->parent;
-		}
-		node = parent;
-	}
-	return node;
-}
-
-/**
- * split off elements number of elements from the start
- * of the name tree and return a new tree 
- */
-ldns_rbtree_t *
-ldns_rbtree_split(ldns_rbtree_t *tree,
-			   size_t elements)
-{
-	ldns_rbtree_t *new_tree;
-	ldns_rbnode_t *cur_node;
-	ldns_rbnode_t *move_node;
-	size_t count = 0;
-
-	new_tree = ldns_rbtree_create(tree->cmp);
-
-	cur_node = ldns_rbtree_first(tree);
-	while (count < elements && cur_node != LDNS_RBTREE_NULL) {
-		move_node = ldns_rbtree_delete(tree, cur_node->key);
-		(void)ldns_rbtree_insert(new_tree, move_node);
-		cur_node = ldns_rbtree_first(tree);
-		count++;
-	}
-
-	return new_tree;
-}
-
-/*
- * add all node from the second tree to the first (removing them from the
- * second), and fix up nsec(3)s if present
- */
-void
-ldns_rbtree_join(ldns_rbtree_t *tree1, ldns_rbtree_t *tree2)
-{
-	ldns_traverse_postorder(tree2, ldns_rbtree_insert_vref, tree1);
-}
-
-/** recursive descent traverse */
-static void 
-traverse_post(void (*func)(ldns_rbnode_t*, void*), void* arg, 
-	ldns_rbnode_t* node)
-{
-	if(!node || node == LDNS_RBTREE_NULL)
-		return;
-	/* recurse */
-	traverse_post(func, arg, node->left);
-	traverse_post(func, arg, node->right);
-	/* call user func */
-	(*func)(node, arg);
-}
-
-void 
-ldns_traverse_postorder(ldns_rbtree_t* tree, 
-	void (*func)(ldns_rbnode_t*, void*), void* arg)
-{
-	traverse_post(func, arg, tree->root);
-}
diff --git a/src/ldns/rdata.c b/src/ldns/rdata.c
deleted file mode 100644
index 6eb0096..0000000
--- a/src/ldns/rdata.c
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * rdata.c
- *
- * rdata implementation
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-/*
- * Access functions 
- * do this as functions to get type checking
- */
-
-/* read */
-size_t
-ldns_rdf_size(const ldns_rdf *rd)
-{
-	assert(rd != NULL);
-	return rd->_size;
-}
-
-ldns_rdf_type
-ldns_rdf_get_type(const ldns_rdf *rd)
-{
-	assert(rd != NULL);
-	return rd->_type;
-}
-
-uint8_t *
-ldns_rdf_data(const ldns_rdf *rd)
-{
-	assert(rd != NULL);
-	return rd->_data;
-}
-
-/* write */
-void
-ldns_rdf_set_size(ldns_rdf *rd, size_t size)
-{
-	assert(rd != NULL);
-	rd->_size = size;
-}
-
-void
-ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type)
-{
-	assert(rd != NULL);
-	rd->_type = type;
-}
-
-void
-ldns_rdf_set_data(ldns_rdf *rd, void *data)
-{
-	/* only copy the pointer */
-	assert(rd != NULL);
-	rd->_data = data;
-}
-
-/* for types that allow it, return
- * the native/host order type */
-uint8_t
-ldns_rdf2native_int8(const ldns_rdf *rd)
-{
-	uint8_t data;
-
-	/* only allow 8 bit rdfs */
-	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_BYTE) {
-		return 0;
-	}
-	
-	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
-	return data;
-}
-
-uint16_t
-ldns_rdf2native_int16(const ldns_rdf *rd)
-{
-	uint16_t data;
-
-	/* only allow 16 bit rdfs */
-	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_WORD) {
-		return 0;
-	}
-	
-	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
-	return ntohs(data);
-}
-
-uint32_t
-ldns_rdf2native_int32(const ldns_rdf *rd)
-{
-	uint32_t data;
-
-	/* only allow 32 bit rdfs */
-	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD) {
-		return 0;
-	}
-	
-	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
-	return ntohl(data);
-}
-
-time_t
-ldns_rdf2native_time_t(const ldns_rdf *rd)
-{
-	uint32_t data;
-
-	/* only allow 32 bit rdfs */
-	if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD ||
-			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_TIME) {
-		return 0;
-	}
-	memcpy(&data, ldns_rdf_data(rd), sizeof(data));
-	return (time_t)ntohl(data);
-}
-
-ldns_rdf *
-ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
-{
-	return ldns_rdf_new_frm_data(type, LDNS_RDF_SIZE_BYTE, &value);
-}
-
-ldns_rdf *
-ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
-{
-	uint16_t *rdf_data = LDNS_XMALLOC(uint16_t, 1);
-        ldns_rdf* rdf;
-	if (!rdf_data) {
-		return NULL;
-	}
-	ldns_write_uint16(rdf_data, value);
-	rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data);
-        if(!rdf)
-                LDNS_FREE(rdf_data);
-        return rdf;
-}
-
-ldns_rdf *
-ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
-{
-	uint32_t *rdf_data = LDNS_XMALLOC(uint32_t, 1);
-        ldns_rdf* rdf;
-	if (!rdf_data) {
-		return NULL;
-	}
-	ldns_write_uint32(rdf_data, value);
-	rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data);
-        if(!rdf)
-                LDNS_FREE(rdf_data);
-        return rdf;
-}
-
-ldns_rdf *
-ldns_native2rdf_int16_data(size_t size, uint8_t *data)
-{
-	uint8_t *rdf_data = LDNS_XMALLOC(uint8_t, size + 2);
-        ldns_rdf* rdf;
-	if (!rdf_data) {
-		return NULL;
-	}
-	ldns_write_uint16(rdf_data, size);
-	memcpy(rdf_data + 2, data, size);
-	rdf = ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data);
-        if(!rdf)
-                LDNS_FREE(rdf_data);
-        return rdf;
-}
-
-/* note: data must be allocated memory */
-ldns_rdf *
-ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
-{
-	ldns_rdf *rd;
-	rd = LDNS_MALLOC(ldns_rdf);
-	if (!rd) {
-		return NULL;
-	}
-	ldns_rdf_set_size(rd, size);
-	ldns_rdf_set_type(rd, type);
-	ldns_rdf_set_data(rd, data);
-	return rd;
-}
-
-ldns_rdf *
-ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
-{
-	ldns_rdf *rdf;
-
-	/* if the size is too big, fail */
-	if (size > LDNS_MAX_RDFLEN) {
-		return NULL;
-	}
-
-	/* allocate space */
-	rdf = LDNS_MALLOC(ldns_rdf);
-	if (!rdf) {
-		return NULL;
-	}
-	rdf->_data = LDNS_XMALLOC(uint8_t, size);
-	if (!rdf->_data) {
-		LDNS_FREE(rdf);
-		return NULL;
-	}
-	
-	/* set the values */
-	ldns_rdf_set_type(rdf, type);
-	ldns_rdf_set_size(rdf, size);
-	memcpy(rdf->_data, data, size);
-
-	return rdf;
-}
-
-ldns_rdf *
-ldns_rdf_clone(const ldns_rdf *rd)
-{
-	assert(rd != NULL);
-	return (ldns_rdf_new_frm_data( ldns_rdf_get_type(rd),
-		ldns_rdf_size(rd), ldns_rdf_data(rd)));
-}
-
-void
-ldns_rdf_deep_free(ldns_rdf *rd)
-{
-	if (rd) {
-		if (rd->_data) {
-			LDNS_FREE(rd->_data);
-		}
-		LDNS_FREE(rd);
-	}
-}
-
-void 
-ldns_rdf_free(ldns_rdf *rd)
-{
-	if (rd) {
-		LDNS_FREE(rd);
-	}
-}
-
-ldns_rdf *
-ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
-{
-	ldns_rdf *rdf = NULL;
-	ldns_status status;
-
-	switch (type) {
-	case LDNS_RDF_TYPE_DNAME:
-		status = ldns_str2rdf_dname(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_INT8:
-		status = ldns_str2rdf_int8(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_INT16:
-		status = ldns_str2rdf_int16(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_INT32:
-		status = ldns_str2rdf_int32(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_A:
-		status = ldns_str2rdf_a(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_AAAA:
-		status = ldns_str2rdf_aaaa(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_STR:
-		status = ldns_str2rdf_str(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_APL:
-		status = ldns_str2rdf_apl(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_B64:
-		status = ldns_str2rdf_b64(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_B32_EXT:
-		status = ldns_str2rdf_b32_ext(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_HEX:
-		status = ldns_str2rdf_hex(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_NSEC:
-		status = ldns_str2rdf_nsec(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_TYPE:
-		status = ldns_str2rdf_type(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_CLASS:
-		status = ldns_str2rdf_class(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_CERT_ALG:
-		status = ldns_str2rdf_cert_alg(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_ALG:
-		status = ldns_str2rdf_alg(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_UNKNOWN:
-		status = ldns_str2rdf_unknown(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_TIME:
-		status = ldns_str2rdf_time(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_PERIOD:
-		status = ldns_str2rdf_period(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_HIP:
-		status = ldns_str2rdf_hip(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_SERVICE:
-		status = ldns_str2rdf_service(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_LOC:
-		status = ldns_str2rdf_loc(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_WKS:
-		status = ldns_str2rdf_wks(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_NSAP:
-		status = ldns_str2rdf_nsap(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_ATMA:
-		status = ldns_str2rdf_atma(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_IPSECKEY:
-		status = ldns_str2rdf_ipseckey(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_NSEC3_SALT:
-		status = ldns_str2rdf_nsec3_salt(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
-		status = ldns_str2rdf_b32_ext(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_ILNP64:
-		status = ldns_str2rdf_ilnp64(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_EUI48:
-		status = ldns_str2rdf_eui48(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_EUI64:
-		status = ldns_str2rdf_eui64(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_TAG:
-		status = ldns_str2rdf_tag(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_LONG_STR:
-		status = ldns_str2rdf_long_str(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
-		status = ldns_str2rdf_certificate_usage(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_SELECTOR:
-		status = ldns_str2rdf_selector(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_MATCHING_TYPE:
-		status = ldns_str2rdf_matching_type(&rdf, str);
-		break;
-	case LDNS_RDF_TYPE_NONE:
-	default:
-		/* default default ??? */
-		status = LDNS_STATUS_ERR;
-		break;
-	}
-	if (LDNS_STATUS_OK == status) {
-		ldns_rdf_set_type(rdf, type);
-		return rdf;
-	}
-	if (rdf) {
-		LDNS_FREE(rdf);
-	}
-	return NULL;
-}
-
-ldns_status
-ldns_rdf_new_frm_fp(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp)
-{
-	return ldns_rdf_new_frm_fp_l(rdf, type, fp, NULL);
-}
-
-ldns_status
-ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr)
-{
-	char *line;
-	ldns_rdf *r;
-	ssize_t t;
-
-	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
-	if (!line) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	/* read an entire line in from the file */
-	if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) {
-		LDNS_FREE(line);
-		return LDNS_STATUS_SYNTAX_RDATA_ERR;
-	}
-	r =  ldns_rdf_new_frm_str(type, (const char*) line);
-	LDNS_FREE(line);
-	if (rdf) {
-		*rdf = r;
-		return LDNS_STATUS_OK;
-	} else {
-		return LDNS_STATUS_NULL;
-	}
-}
-
-ldns_rdf *
-ldns_rdf_address_reverse(ldns_rdf *rd)
-{
-	uint8_t buf_4[LDNS_IP4ADDRLEN];
-	uint8_t buf_6[LDNS_IP6ADDRLEN * 2];
-	ldns_rdf *rev;
-	ldns_rdf *in_addr;
-	ldns_rdf *ret_dname;
-	uint8_t octet;
-	uint8_t nnibble;
-	uint8_t nibble;
-	uint8_t i, j;
-
-	char *char_dname;
-	int nbit;
-
-	if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_A &&
-			ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_AAAA) {
-		return NULL;
-	}
-
-	in_addr = NULL;
-	ret_dname = NULL;
-
-	switch(ldns_rdf_get_type(rd)) {
-		case LDNS_RDF_TYPE_A:
-			/* the length of the buffer is 4 */
-			buf_4[3] = ldns_rdf_data(rd)[0];
-			buf_4[2] = ldns_rdf_data(rd)[1];
-			buf_4[1] = ldns_rdf_data(rd)[2];
-			buf_4[0] = ldns_rdf_data(rd)[3];
-			in_addr = ldns_dname_new_frm_str("in-addr.arpa.");
-			if (!in_addr) {
-				return NULL;
-			}
-			/* make a new rdf and convert that back  */
-			rev = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_A,
-				LDNS_IP4ADDRLEN, (void*)&buf_4);
-			if (!rev) {
-				LDNS_FREE(in_addr);
-				return NULL;
-			}
-
-			/* convert rev to a string */
-			char_dname = ldns_rdf2str(rev);
-			if (!char_dname) {
-				LDNS_FREE(in_addr);
-				ldns_rdf_deep_free(rev);
-				return NULL;
-			}
-			/* transform back to rdf with type dname */
-			ret_dname = ldns_dname_new_frm_str(char_dname);
-			if (!ret_dname) {
-				LDNS_FREE(in_addr);
-				ldns_rdf_deep_free(rev);
-				LDNS_FREE(char_dname);
-				return NULL;
-			}
-			/* not needed anymore */
-			ldns_rdf_deep_free(rev);
-			LDNS_FREE(char_dname);
-			break;
-		case LDNS_RDF_TYPE_AAAA:
-			/* some foo magic to reverse the nibbles ... */
-
-			for (nbit = 127; nbit >= 0; nbit = nbit - 4) {
-				/* calculate octett (8 bit) */
-				octet = ( ((unsigned int) nbit) & 0x78) >> 3;
-				/* calculate nibble */
-				nnibble = ( ((unsigned int) nbit) & 0x04) >> 2;
-				/* extract nibble */
-				nibble = (ldns_rdf_data(rd)[octet] & ( 0xf << (4 * (1 -
-						 nnibble)) ) ) >> ( 4 * (1 - 
-						nnibble));
-
-				buf_6[(LDNS_IP6ADDRLEN * 2 - 1) -
-					(octet * 2 + nnibble)] = 
-						(uint8_t)ldns_int_to_hexdigit((int)nibble);
-			}
-
-			char_dname = LDNS_XMALLOC(char, (LDNS_IP6ADDRLEN * 4));
-			if (!char_dname) {
-				return NULL;
-			}
-			char_dname[LDNS_IP6ADDRLEN * 4 - 1] = '\0'; /* closure */
-
-			/* walk the string and add . 's */
-			for (i = 0, j = 0; i < LDNS_IP6ADDRLEN * 2; i++, j = j + 2) {
-				char_dname[j] = (char)buf_6[i];
-				if (i != LDNS_IP6ADDRLEN * 2 - 1) {
-					char_dname[j + 1] = '.';
-				}
-			}
-			in_addr = ldns_dname_new_frm_str("ip6.arpa.");
-			if (!in_addr) {
-				LDNS_FREE(char_dname);
-				return NULL;
-			}
-
-			/* convert rev to a string */
-			ret_dname = ldns_dname_new_frm_str(char_dname);
-			LDNS_FREE(char_dname);
-			if (!ret_dname) {
-				ldns_rdf_deep_free(in_addr);
-				return NULL;
-			}
-			break;
-		default:
-			break;
-	}
-	/* add the suffix */
-	rev = ldns_dname_cat_clone(ret_dname, in_addr);
-
-	ldns_rdf_deep_free(ret_dname);
-	ldns_rdf_deep_free(in_addr);
-	return rev;
-}
-
-ldns_status
-ldns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg,
-                            uint8_t *hit_size, uint8_t** hit,
-                            uint16_t *pk_size, uint8_t** pk)
-{
-	uint8_t *data;
-	size_t rdf_size;
-
-	if (! rdf || ! alg || ! hit || ! hit_size || ! pk || ! pk_size) {
-		return LDNS_STATUS_INVALID_POINTER;
-	} else if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_HIP) {
-		return LDNS_STATUS_INVALID_RDF_TYPE;
-	} else if ((rdf_size = ldns_rdf_size(rdf)) < 6) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	data = ldns_rdf_data(rdf);
-	*hit_size = data[0];
-	*alg      = data[1];
-	*pk_size  = ldns_read_uint16(data + 2);
-	*hit      = data + 4;
-	*pk       = data + 4 + *hit_size;
-	if (*hit_size == 0 || *pk_size == 0 ||
-			rdf_size < (size_t) *hit_size + *pk_size + 4) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf** rdf, uint8_t alg,
-                                uint8_t hit_size, uint8_t *hit,
-				uint16_t pk_size, uint8_t *pk)
-{
-	uint8_t *data;
-
-	if (! rdf) {
-		return LDNS_STATUS_INVALID_POINTER;
-	}
-	if (4 + hit_size + pk_size > LDNS_MAX_RDFLEN) {
-		return LDNS_STATUS_RDATA_OVERFLOW;
-	}
-	data = LDNS_XMALLOC(uint8_t, 4 + hit_size + pk_size);
-	if (data == NULL) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	data[0] = hit_size;
-	data[1] = alg;
-	ldns_write_uint16(data + 2, pk_size);
-	memcpy(data + 4, hit, hit_size);
-	memcpy(data + 4 + hit_size, pk, pk_size);
-	*rdf = ldns_rdf_new(LDNS_RDF_TYPE_HIP, 4 + hit_size + pk_size, data);
-	if (! *rdf) {
-		LDNS_FREE(data);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_octet(char *word, size_t *length)
-{
-    char *s; 
-    char *p;
-    *length = 0;
-
-    for (s = p = word; *s != '\0'; s++,p++) {
-        switch (*s) {
-            case '.':
-                if (s[1] == '.') {
-		    return LDNS_STATUS_EMPTY_LABEL;
-                }
-                *p = *s;
-                (*length)++;
-                break;
-            case '\\':
-                if ('0' <= s[1] && s[1] <= '9' &&
-                    '0' <= s[2] && s[2] <= '9' &&
-                    '0' <= s[3] && s[3] <= '9') {
-                    /* \DDD seen */
-                    int val = ((s[1] - '0') * 100 +
-                           (s[2] - '0') * 10 + (s[3] - '0'));
-
-                    if (0 <= val && val <= 255) {
-                        /* this also handles \0 */
-                        s += 3;
-                        *p = val;
-                        (*length)++;
-                    } else {
-                        return LDNS_STATUS_DDD_OVERFLOW;
-                    }
-                } else {
-                    /* an espaced character, like \<space> ? 
-                    * remove the '\' keep the rest */
-                    *p = *++s;
-                    (*length)++;
-                }
-                break;
-            case '\"':
-                /* non quoted " Is either first or the last character in
-                 * the string */
-
-                *p = *++s; /* skip it */
-                (*length)++;
-		/* I'm not sure if this is needed in libdns... MG */
-                if ( *s == '\0' ) {
-                    /* ok, it was the last one */
-                    *p  = '\0'; 
-		    return LDNS_STATUS_OK;
-                }
-                break;
-            default:
-                *p = *s;
-                (*length)++;
-                break;
-        }
-    }
-    *p = '\0';
-    return LDNS_STATUS_OK;
-}
-
-int
-ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
-{
-	uint16_t i1, i2, i;
-	uint8_t *d1, *d2;
-
-	/* only when both are not NULL we can say anything about them */
-	if (!rd1 && !rd2) {
-		return 0;
-	}
-	if (!rd1 || !rd2) {
-		return -1;
-	}
-	i1 = ldns_rdf_size(rd1);
-	i2 = ldns_rdf_size(rd2);
-
-	if (i1 < i2) {
-		return -1;
-	} else if (i1 > i2) {
-		return +1;
-	} else {
-		d1 = (uint8_t*)ldns_rdf_data(rd1);
-		d2 = (uint8_t*)ldns_rdf_data(rd2);
-		for(i = 0; i < i1; i++) {
-			if (d1[i] < d2[i]) {
-				return -1;
-			} else if (d1[i] > d2[i]) {
-				return +1;
-			}
-		}
-	}
-	return 0;
-}
-
-uint32_t
-ldns_str2period(const char *nptr, const char **endptr)
-{
-	int sign = 0;
-	uint32_t i = 0;
-	uint32_t seconds = 0;
-
-	for(*endptr = nptr; **endptr; (*endptr)++) {
-		switch (**endptr) {
-			case ' ':
-			case '\t':
-				break;
-			case '-':
-				if(sign == 0) {
-					sign = -1;
-				} else {
-					return seconds;
-				}
-				break;
-			case '+':
-				if(sign == 0) {
-					sign = 1;
-				} else {
-					return seconds;
-				}
-				break;
-			case 's':
-			case 'S':
-				seconds += i;
-				i = 0;
-				break;
-			case 'm':
-			case 'M':
-				seconds += i * 60;
-				i = 0;
-				break;
-			case 'h':
-			case 'H':
-				seconds += i * 60 * 60;
-				i = 0;
-				break;
-			case 'd':
-			case 'D':
-				seconds += i * 60 * 60 * 24;
-				i = 0;
-				break;
-			case 'w':
-			case 'W':
-				seconds += i * 60 * 60 * 24 * 7;
-				i = 0;
-				break;
-			case '0':
-			case '1':
-			case '2':
-			case '3':
-			case '4':
-			case '5':
-			case '6':
-			case '7':
-			case '8':
-			case '9':
-				i *= 10;
-				i += (**endptr - '0');
-				break;
-			default:
-				seconds += i;
-				/* disregard signedness */
-				return seconds;
-		}
-	}
-	seconds += i;
-	/* disregard signedness */
-	return seconds;
-}
diff --git a/src/ldns/resolver.c b/src/ldns/resolver.c
deleted file mode 100644
index b092404..0000000
--- a/src/ldns/resolver.c
+++ /dev/null
@@ -1,1603 +0,0 @@
-/*
- * resolver.c
- *
- * resolver implementation
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-#include <strings.h>
-
-/* Access function for reading
- * and setting the different Resolver
- * options */
-
-/* read */
-uint16_t
-ldns_resolver_port(const ldns_resolver *r)
-{
-	return r->_port;
-}
-
-ldns_rdf *
-ldns_resolver_source(const ldns_resolver *r)
-{
-	return r->_source;
-}
-
-uint16_t
-ldns_resolver_edns_udp_size(const ldns_resolver *r)
-{
-	        return r->_edns_udp_size;
-}
-
-uint8_t
-ldns_resolver_retry(const ldns_resolver *r)
-{
-	return r->_retry;
-}
-
-uint8_t
-ldns_resolver_retrans(const ldns_resolver *r)
-{
-	return r->_retrans;
-}
-
-bool
-ldns_resolver_fallback(const ldns_resolver *r)
-{
-	return r->_fallback;
-}
-
-uint8_t
-ldns_resolver_ip6(const ldns_resolver *r)
-{
-	return r->_ip6;
-}
-
-bool
-ldns_resolver_recursive(const ldns_resolver *r)
-{
-	return r->_recursive;
-}
-
-bool
-ldns_resolver_debug(const ldns_resolver *r)
-{
-	return r->_debug;
-}
-
-bool
-ldns_resolver_dnsrch(const ldns_resolver *r)
-{
-	return r->_dnsrch;
-}
-
-bool
-ldns_resolver_fail(const ldns_resolver *r)
-{
-	return r->_fail;
-}
-
-bool
-ldns_resolver_defnames(const ldns_resolver *r)
-{
-	return r->_defnames;
-}
-
-ldns_rdf *
-ldns_resolver_domain(const ldns_resolver *r)
-{
-	return r->_domain;
-}
-
-ldns_rdf **
-ldns_resolver_searchlist(const ldns_resolver *r)
-{
-	return r->_searchlist;
-}
-
-ldns_rdf **
-ldns_resolver_nameservers(const ldns_resolver *r)
-{
-	return r->_nameservers;
-}
-
-size_t
-ldns_resolver_nameserver_count(const ldns_resolver *r)
-{
-	return r->_nameserver_count;
-}
-
-bool
-ldns_resolver_dnssec(const ldns_resolver *r)
-{
-	return r->_dnssec;
-}
-
-bool
-ldns_resolver_dnssec_cd(const ldns_resolver *r)
-{
-	return r->_dnssec_cd;
-}
-
-ldns_rr_list *
-ldns_resolver_dnssec_anchors(const ldns_resolver *r)
-{
-    return r->_dnssec_anchors;
-}
-
-bool
-ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys)
-{
-  size_t i;
-  bool result = false;
-
-  ldns_rr_list * trust_anchors;
-  ldns_rr * cur_rr;
-
-  if (!r || !keys) { return false; }
-
-  trust_anchors = ldns_resolver_dnssec_anchors(r);
-
-  if (!trust_anchors) { return false; }
-
-  for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
-
-    cur_rr = ldns_rr_list_rr(keys, i);
-    if (ldns_rr_list_contains_rr(trust_anchors, cur_rr)) {
-      if (trusted_keys) { ldns_rr_list_push_rr(trusted_keys, cur_rr); }
-      result = true;
-    }
-  }
-
-  return result;
-}
-
-bool
-ldns_resolver_igntc(const ldns_resolver *r)
-{
-	return r->_igntc;
-}
-
-bool
-ldns_resolver_usevc(const ldns_resolver *r)
-{
-	return r->_usevc;
-}
-
-size_t *
-ldns_resolver_rtt(const ldns_resolver *r)
-{
-	return r->_rtt;
-}
-
-size_t
-ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos)
-{
-	size_t *rtt;
-
-	assert(r != NULL);
-
-	rtt = ldns_resolver_rtt(r);
-
-	if (pos >= ldns_resolver_nameserver_count(r)) {
-		/* error ?*/
-		return 0;
-	} else {
-		return rtt[pos];
-	}
-
-}
-
-struct timeval
-ldns_resolver_timeout(const ldns_resolver *r)
-{
-	return r->_timeout;
-}
-
-char *
-ldns_resolver_tsig_keyname(const ldns_resolver *r)
-{
-	return r->_tsig_keyname;
-}
-
-char *
-ldns_resolver_tsig_algorithm(const ldns_resolver *r)
-{
-	return r->_tsig_algorithm;
-}
-
-char *
-ldns_resolver_tsig_keydata(const ldns_resolver *r)
-{
-	return r->_tsig_keydata;
-}
-
-bool
-ldns_resolver_random(const ldns_resolver *r)
-{
-	return r->_random;
-}
-
-size_t
-ldns_resolver_searchlist_count(const ldns_resolver *r)
-{
-	return r->_searchlist_count;
-}
-
-/* write */
-void
-ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
-{
-	r->_port = p;
-}
-
-void
-ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s)
-{
-	r->_source = s;
-}
-
-ldns_rdf *
-ldns_resolver_pop_nameserver(ldns_resolver *r)
-{
-	ldns_rdf **nameservers;
-	ldns_rdf *pop;
-	size_t ns_count;
-	size_t *rtt;
-
-	assert(r != NULL);
-
-	ns_count = ldns_resolver_nameserver_count(r);
-	nameservers = ldns_resolver_nameservers(r);
-	rtt = ldns_resolver_rtt(r);
-	if (ns_count == 0 || !nameservers) {
-		return NULL;
-	}
-
-	pop = nameservers[ns_count - 1];
-
-	if (ns_count == 1) {
-		LDNS_FREE(nameservers);
-		LDNS_FREE(rtt);
-
-		ldns_resolver_set_nameservers(r, NULL);
-		ldns_resolver_set_rtt(r, NULL);
-	} else {
-		nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, 
-				(ns_count - 1));
-		rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
-
-	        ldns_resolver_set_nameservers(r, nameservers);
-	        ldns_resolver_set_rtt(r, rtt);
-	}
-	/* decr the count */
-	ldns_resolver_dec_nameserver_count(r);
-	return pop;
-}
-
-ldns_status
-ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n)
-{
-	ldns_rdf **nameservers;
-	size_t ns_count;
-	size_t *rtt;
-
-	if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A &&
-			ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) {
-		return LDNS_STATUS_ERR;
-	}
-
-	ns_count = ldns_resolver_nameserver_count(r);
-	nameservers = ldns_resolver_nameservers(r);
-	rtt = ldns_resolver_rtt(r);
-
-	/* make room for the next one */
-	if (ns_count == 0) {
-		nameservers = LDNS_XMALLOC(ldns_rdf *, 1);
-	} else {
-		nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
-	}
-        if(!nameservers)
-                return LDNS_STATUS_MEM_ERR;
-
-	/* set the new value in the resolver */
-	ldns_resolver_set_nameservers(r, nameservers);
-
-	/* don't forget the rtt */
-	if (ns_count == 0) {
-		rtt = LDNS_XMALLOC(size_t, 1);
-	} else {
-		rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
-	}
-        if(!rtt)
-                return LDNS_STATUS_MEM_ERR;
-
-	/* slide n in its slot. */
-	/* we clone it here, because then we can free the original
-	 * rr's where it stood */
-	nameservers[ns_count] = ldns_rdf_clone(n);
-	rtt[ns_count] = LDNS_RESOLV_RTT_MIN;
-	ldns_resolver_incr_nameserver_count(r);
-	ldns_resolver_set_rtt(r, rtt);
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr)
-{
-	ldns_rdf *address;
-	if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
-			ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) {
-		return LDNS_STATUS_ERR;
-	}
-	address = ldns_rr_rdf(rr, 0); /* extract the ip number */
-	if (address) {
-		return ldns_resolver_push_nameserver(r, address);
-	} else {
-		return LDNS_STATUS_ERR;
-	}
-}
-
-ldns_status
-ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list *rrlist)
-{
-	ldns_rr *rr;
-	ldns_status stat;
-	size_t i;
-
-	stat = LDNS_STATUS_OK;
-	if (rrlist) {
-		for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
-			rr = ldns_rr_list_rr(rrlist, i);
-			if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) {
-				stat = LDNS_STATUS_ERR;
-				break;
-			}
-		}
-		return stat;
-	} else {
-		return LDNS_STATUS_ERR;
-	}
-}
-
-void
-ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
-{
-	        r->_edns_udp_size = s;
-}
-
-void
-ldns_resolver_set_recursive(ldns_resolver *r, bool re)
-{
-	r->_recursive = re;
-}
-
-void
-ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
-{
-	r->_dnssec = d;
-}
-
-void
-ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
-{
-	r->_dnssec_cd = d;
-}
-
-void
-ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
-{
-  r->_dnssec_anchors = l;
-}
-
-ldns_status
-ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
-{
-  ldns_rr_list * trust_anchors;
-
-  if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
-                ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS)) {
-
-    return LDNS_STATUS_ERR;
-  }
-
-  if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
-    trust_anchors = ldns_rr_list_new();
-    ldns_resolver_set_dnssec_anchors(r, trust_anchors);
-  }
-
-  return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
-}
-
-void
-ldns_resolver_set_igntc(ldns_resolver *r, bool i)
-{
-	r->_igntc = i;
-}
-
-void
-ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
-{
-	r->_usevc = vc;
-}
-
-void
-ldns_resolver_set_debug(ldns_resolver *r, bool d)
-{
-	r->_debug = d;
-}
-
-void
-ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
-{
-	r->_ip6 = ip6;
-}
-
-void
-ldns_resolver_set_fail(ldns_resolver *r, bool f)
-{
-	r->_fail =f;
-}
-
-static void
-ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
-{
-	r->_searchlist_count = c;
-}
-
-void
-ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
-{
-	r->_nameserver_count = c;
-}
-
-void
-ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
-{
-	r->_dnsrch = d;
-}
-
-void
-ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
-{
-	r->_retry = retry;
-}
-
-void
-ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
-{
-	r->_retrans = retrans;
-}
-
-void
-ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
-{
-	r->_fallback = fallback;
-}
-
-void
-ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
-{
-	r->_nameservers = n;
-}
-
-void
-ldns_resolver_set_defnames(ldns_resolver *r, bool d)
-{
-	r->_defnames = d;
-}
-
-void
-ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
-{
-	r->_rtt = rtt;
-}
-
-void
-ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
-{
-	size_t *rtt;
-
-	assert(r != NULL);
-
-	rtt = ldns_resolver_rtt(r);
-
-	if (pos >= ldns_resolver_nameserver_count(r)) {
-		/* error ?*/
-	} else {
-		rtt[pos] = value;
-	}
-
-}
-
-void
-ldns_resolver_incr_nameserver_count(ldns_resolver *r)
-{
-	size_t c;
-
-	c = ldns_resolver_nameserver_count(r);
-	ldns_resolver_set_nameserver_count(r, ++c);
-}
-
-void
-ldns_resolver_dec_nameserver_count(ldns_resolver *r)
-{
-	size_t c;
-
-	c = ldns_resolver_nameserver_count(r);
-	if (c == 0) {
-		return;
-	} else {
-		ldns_resolver_set_nameserver_count(r, --c);
-	}
-}
-
-void
-ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
-{
-	r->_domain = d;
-}
-
-void
-ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
-{
-	r->_timeout.tv_sec = timeout.tv_sec;
-	r->_timeout.tv_usec = timeout.tv_usec;
-}
-
-void
-ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
-{
-	ldns_rdf **searchlist;
-	size_t list_count;
-
-	if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
-		return;
-	}
-
-	list_count = ldns_resolver_searchlist_count(r);
-	searchlist = ldns_resolver_searchlist(r);
-
-	searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1));
-	if (searchlist) {
-		r->_searchlist = searchlist;
-
-		searchlist[list_count] = ldns_rdf_clone(d);
-		ldns_resolver_set_searchlist_count(r, list_count + 1);
-	} /* no way to report mem err */
-}
-
-void
-ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname)
-{
-	LDNS_FREE(r->_tsig_keyname);
-	r->_tsig_keyname = strdup(tsig_keyname);
-}
-
-void
-ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm)
-{
-	LDNS_FREE(r->_tsig_algorithm);
-	r->_tsig_algorithm = strdup(tsig_algorithm);
-}
-
-void
-ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata)
-{
-	LDNS_FREE(r->_tsig_keydata);
-	r->_tsig_keydata = strdup(tsig_keydata);
-}
-
-void
-ldns_resolver_set_random(ldns_resolver *r, bool b)
-{
-	r->_random = b;
-}
-
-/* more sophisticated functions */
-ldns_resolver *
-ldns_resolver_new(void)
-{
-	ldns_resolver *r;
-
-	r = LDNS_MALLOC(ldns_resolver);
-	if (!r) {
-		return NULL;
-	}
-
-	r->_searchlist = NULL;
-	r->_nameservers = NULL;
-	r->_rtt = NULL;
-
-	/* defaults are filled out */
-	ldns_resolver_set_searchlist_count(r, 0);
-	ldns_resolver_set_nameserver_count(r, 0);
-	ldns_resolver_set_usevc(r, 0);
-	ldns_resolver_set_port(r, LDNS_PORT);
-	ldns_resolver_set_domain(r, NULL);
-	ldns_resolver_set_defnames(r, false);
-	ldns_resolver_set_retry(r, 3);
-	ldns_resolver_set_retrans(r, 2);
-	ldns_resolver_set_fallback(r, true);
-	ldns_resolver_set_fail(r, false);
-	ldns_resolver_set_edns_udp_size(r, 0);
-	ldns_resolver_set_dnssec(r, false);
-	ldns_resolver_set_dnssec_cd(r, false);
-	ldns_resolver_set_dnssec_anchors(r, NULL);
-	ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
-	ldns_resolver_set_igntc(r, false);
-	ldns_resolver_set_recursive(r, false);
-	ldns_resolver_set_dnsrch(r, true);
-	ldns_resolver_set_source(r, NULL);
-	ldns_resolver_set_ixfr_serial(r, 0);
-
-	/* randomize the nameserver to be queried
-	 * when there are multiple
-	 */
-	ldns_resolver_set_random(r, true);
-
-	ldns_resolver_set_debug(r, 0);
-
-	r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
-	r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
-
-	/* TODO: fd=0 is actually a valid socket (stdin),
-           replace with -1 */
-	r->_socket = 0;
-	r->_axfr_soa_count = 0;
-	r->_axfr_i = 0;
-	r->_cur_axfr_pkt = NULL;
-
-	r->_tsig_keyname = NULL;
-	r->_tsig_keydata = NULL;
-	r->_tsig_algorithm = NULL;
-	return r;
-}
-
-ldns_resolver *
-ldns_resolver_clone(ldns_resolver *src)
-{
-	ldns_resolver *dst;
-	size_t i;
-
-	assert(src != NULL);
-
-	if (!(dst = LDNS_MALLOC(ldns_resolver))) return NULL;
-	(void) memcpy(dst, src, sizeof(ldns_resolver));
-
-	if (dst->_searchlist_count == 0)
-		dst->_searchlist = NULL;
-	else {
-		if (!(dst->_searchlist =
-		    LDNS_XMALLOC(ldns_rdf *, dst->_searchlist_count)))
-			goto error;
-		for (i = 0; i < dst->_searchlist_count; i++)
-			if (!(dst->_searchlist[i] =
-			    ldns_rdf_clone(src->_searchlist[i]))) {
-				dst->_searchlist_count = i;
-				goto error_searchlist;
-			}
-	}
-	if (dst->_nameserver_count == 0) {
-		dst->_nameservers = NULL;
-		dst->_rtt = NULL;
-	} else {
-		if (!(dst->_nameservers =
-		    LDNS_XMALLOC(ldns_rdf *, dst->_nameserver_count)))
-			goto error_searchlist;
-		for (i = 0; i < dst->_nameserver_count; i++)
-			if (!(dst->_nameservers[i] =
-			    ldns_rdf_clone(src->_nameservers[i]))) {
-				dst->_nameserver_count = i;
-				goto error_nameservers;
-			}
-		if (!(dst->_rtt =
-		    LDNS_XMALLOC(size_t, dst->_nameserver_count)))
-			goto error_nameservers;
-		(void) memcpy(dst->_rtt, src->_rtt,
-		    sizeof(size_t) * dst->_nameserver_count);
-	}
-	if (dst->_domain && (!(dst->_domain = ldns_rdf_clone(src->_domain))))
-		goto error_rtt;
-
-	if (dst->_tsig_keyname &&
-	    (!(dst->_tsig_keyname = strdup(src->_tsig_keyname))))
-		goto error_domain;
-
-	if (dst->_tsig_keydata &&
-	    (!(dst->_tsig_keydata = strdup(src->_tsig_keydata))))
-		goto error_tsig_keyname;
-
-	if (dst->_tsig_algorithm &&
-	    (!(dst->_tsig_algorithm = strdup(src->_tsig_algorithm))))
-		goto error_tsig_keydata;
-
-	if (dst->_cur_axfr_pkt &&
-	    (!(dst->_cur_axfr_pkt = ldns_pkt_clone(src->_cur_axfr_pkt))))
-		goto error_tsig_algorithm;
-
-	if (dst->_dnssec_anchors &&
-	    (!(dst->_dnssec_anchors=ldns_rr_list_clone(src->_dnssec_anchors))))
-		goto error_cur_axfr_pkt;
-
-	return dst;
-
-error_cur_axfr_pkt:
-	ldns_pkt_free(dst->_cur_axfr_pkt);
-error_tsig_algorithm:
-	LDNS_FREE(dst->_tsig_algorithm);
-error_tsig_keydata:
-	LDNS_FREE(dst->_tsig_keydata);
-error_tsig_keyname:
-	LDNS_FREE(dst->_tsig_keyname);
-error_domain:
-	ldns_rdf_deep_free(dst->_domain);
-error_rtt:
-	LDNS_FREE(dst->_rtt);
-error_nameservers:
-	for (i = 0; i < dst->_nameserver_count; i++)
-		ldns_rdf_deep_free(dst->_nameservers[i]);
-	LDNS_FREE(dst->_nameservers);
-error_searchlist:
-	for (i = 0; i < dst->_searchlist_count; i++)
-		ldns_rdf_deep_free(dst->_searchlist[i]);
-	LDNS_FREE(dst->_searchlist);
-error:
-	LDNS_FREE(dst);
-	return NULL;
-}
-
-
-ldns_status
-ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
-{
-	return ldns_resolver_new_frm_fp_l(res, fp, NULL);
-}
-
-ldns_status
-ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
-{
-	ldns_resolver *r;
-	const char *keyword[LDNS_RESOLV_KEYWORDS];
-	char word[LDNS_MAX_LINELEN + 1];
-	int8_t expect;
-	uint8_t i;
-	ldns_rdf *tmp;
-#ifdef HAVE_SSL
-	ldns_rr *tmp_rr;
-#endif
-	ssize_t gtr, bgtr;
-	ldns_buffer *b;
-        int lnr = 0, oldline;
-	FILE* myfp = fp;
-        if(!line_nr) line_nr = &lnr;
-
-	if(!fp) {
-		myfp = fopen("/etc/resolv.conf", "r");
-		if(!myfp)
-			return LDNS_STATUS_FILE_ERR;
-	}
-
-	/* do this better
-	 * expect =
-	 * 0: keyword
-	 * 1: default domain dname
-	 * 2: NS aaaa or a record
-	 */
-
-	/* recognized keywords */
-	keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
-	keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
-	keyword[LDNS_RESOLV_SEARCH] = "search";
-	/* these two are read but not used atm TODO */
-	keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
-	keyword[LDNS_RESOLV_OPTIONS] = "options";
-	keyword[LDNS_RESOLV_ANCHOR] = "anchor";
-	expect = LDNS_RESOLV_KEYWORD;
-
-	r = ldns_resolver_new();
-	if (!r) {
-		if(!fp) fclose(myfp);
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	gtr = 1;
-	word[0] = 0;
-        oldline = *line_nr;
-        expect = LDNS_RESOLV_KEYWORD;
-	while (gtr > 0) {
-		/* check comments */
-		if (word[0] == '#') {
-                        word[0]='x';
-                        if(oldline == *line_nr) {
-                                /* skip until end of line */
-                                int c;
-                                do {
-                                        c = fgetc(myfp);
-                                } while(c != EOF && c != '\n');
-                                if(c=='\n') (*line_nr)++;
-                        }
-			/* and read next to prepare for further parsing */
-                        oldline = *line_nr;
-			continue;
-		}
-                oldline = *line_nr;
-		switch(expect) {
-			case LDNS_RESOLV_KEYWORD:
-				/* keyword */
-				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
-				if (gtr != 0) {
-                                        if(word[0] == '#') continue;
-					for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
-						if (strcasecmp(keyword[i], word) == 0) {
-							/* chosen the keyword and
-							 * expect values carefully
-	        					 */
-							expect = i;
-							break;
-						}
-					}
-					/* no keyword recognized */
-					if (expect == LDNS_RESOLV_KEYWORD) {
-						/* skip line */
-						/*
-						ldns_resolver_deep_free(r);
-						if(!fp) fclose(myfp);
-						return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
-						*/
-					}
-				}
-				break;
-			case LDNS_RESOLV_DEFDOMAIN:
-				/* default domain dname */
-				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
-				if (gtr == 0) {
-					if(!fp) fclose(myfp);
-					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
-				}
-                                if(word[0] == '#') {
-                                        expect = LDNS_RESOLV_KEYWORD;
-                                        continue;
-                                }
-				tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
-				if (!tmp) {
-					ldns_resolver_deep_free(r);
-					if(!fp) fclose(myfp);
-					return LDNS_STATUS_SYNTAX_DNAME_ERR;
-				}
-
-				/* DOn't free, because we copy the pointer */
-				ldns_resolver_set_domain(r, tmp);
-				expect = LDNS_RESOLV_KEYWORD;
-				break;
-			case LDNS_RESOLV_NAMESERVER:
-				/* NS aaaa or a record */
-				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
-				if (gtr == 0) {
-					if(!fp) fclose(myfp);
-					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
-				}
-                                if(word[0] == '#') {
-                                        expect = LDNS_RESOLV_KEYWORD;
-                                        continue;
-                                }
-                                if(strchr(word, '%')) {
-                                        /* snip off interface labels,
-                                         * fe80::222:19ff:fe31:4222%eth0 */
-                                        strchr(word, '%')[0]=0;
-                                }
-				tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
-				if (!tmp) {
-					/* try ip4 */
-					tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
-				}
-				/* could not parse it, exit */
-				if (!tmp) {
-					ldns_resolver_deep_free(r);
-					if(!fp) fclose(myfp);
-					return LDNS_STATUS_SYNTAX_ERR;
-				}
-				(void)ldns_resolver_push_nameserver(r, tmp);
-				ldns_rdf_deep_free(tmp);
-				expect = LDNS_RESOLV_KEYWORD;
-				break;
-			case LDNS_RESOLV_SEARCH:
-				/* search list domain dname */
-				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
-				b = LDNS_MALLOC(ldns_buffer);
-				if(!b) {
-					ldns_resolver_deep_free(r);
-					if(!fp) fclose(myfp);
-					return LDNS_STATUS_MEM_ERR;
-				}
-
-				ldns_buffer_new_frm_data(b, word, (size_t) gtr);
-				if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
-					LDNS_FREE(b);
-					ldns_resolver_deep_free(r);
-					if(!fp) fclose(myfp);
-					return LDNS_STATUS_MEM_ERR;
-				}
-				bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
-				while (bgtr > 0) {
-					gtr -= bgtr;
-                                        if(word[0] == '#') {
-                                                expect = LDNS_RESOLV_KEYWORD;
-                                                break;
-                                        }
-					tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
-					if (!tmp) {
-						ldns_resolver_deep_free(r);
-						ldns_buffer_free(b);
-						if(!fp) fclose(myfp);
-						return LDNS_STATUS_SYNTAX_DNAME_ERR;
-					}
-
-					ldns_resolver_push_searchlist(r, tmp);
-
-					ldns_rdf_deep_free(tmp);
-					bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
-					    (size_t) gtr + 1);
-				}
-				ldns_buffer_free(b);
-				if (expect != LDNS_RESOLV_KEYWORD) {
-					gtr = 1;
-					expect = LDNS_RESOLV_KEYWORD;
-				}
-				break;
-			case LDNS_RESOLV_SORTLIST:
-				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
-				/* sortlist not implemented atm */
-				expect = LDNS_RESOLV_KEYWORD;
-				break;
-			case LDNS_RESOLV_OPTIONS:
-				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
-				/* options not implemented atm */
-				expect = LDNS_RESOLV_KEYWORD;
-				break;
-			case LDNS_RESOLV_ANCHOR:
-				/* a file containing a DNSSEC trust anchor */
-				gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
-				if (gtr == 0) {
-					ldns_resolver_deep_free(r);
-					if(!fp) fclose(myfp);
-					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
-				}
-                                if(word[0] == '#') {
-                                        expect = LDNS_RESOLV_KEYWORD;
-                                        continue;
-                                }
-
-#ifdef HAVE_SSL
-				tmp_rr = ldns_read_anchor_file(word);
-				(void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
-				ldns_rr_free(tmp_rr);
-#endif
-				expect = LDNS_RESOLV_KEYWORD;
-				break;
-		}
-	}
-
-	if(!fp)
-		fclose(myfp);
-
-	if (res) {
-		*res = r;
-		return LDNS_STATUS_OK;
-	} else {
-		ldns_resolver_deep_free(r);
-		return LDNS_STATUS_NULL;
-	}
-}
-
-ldns_status
-ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
-{
-	ldns_resolver *r;
-	FILE *fp;
-	ldns_status s;
-
-	if (!filename) {
-		fp = fopen(LDNS_RESOLV_CONF, "r");
-
-	} else {
-		fp = fopen(filename, "r");
-	}
-	if (!fp) {
-		return LDNS_STATUS_FILE_ERR;
-	}
-
-	s = ldns_resolver_new_frm_fp(&r, fp);
-	fclose(fp);
-	if (s == LDNS_STATUS_OK) {
-		if (res) {
-			*res = r;
-			return LDNS_STATUS_OK;
-		} else  {
-			ldns_resolver_free(r);
-			return LDNS_STATUS_NULL;
-		}
-	}
-	return s;
-}
-
-void
-ldns_resolver_free(ldns_resolver *res)
-{
-	LDNS_FREE(res);
-}
-
-void
-ldns_resolver_deep_free(ldns_resolver *res)
-{
-	size_t i;
-
-	if (res) {
-		if (res->_searchlist) {
-			for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
-				ldns_rdf_deep_free(res->_searchlist[i]);
-			}
-			LDNS_FREE(res->_searchlist);
-		}
-		if (res->_nameservers) {
-			for (i = 0; i < res->_nameserver_count; i++) {
-				ldns_rdf_deep_free(res->_nameservers[i]);
-			}
-			LDNS_FREE(res->_nameservers);
-		}
-		if (ldns_resolver_domain(res)) {
-			ldns_rdf_deep_free(ldns_resolver_domain(res));
-		}
-		if (res->_tsig_keyname) {
-			LDNS_FREE(res->_tsig_keyname);
-		}
-		if (res->_tsig_keydata) {
-			LDNS_FREE(res->_tsig_keydata);
-		}
-		if (res->_tsig_algorithm) {
-			LDNS_FREE(res->_tsig_algorithm);
-		}
-
-		if (res->_cur_axfr_pkt) {
-			ldns_pkt_free(res->_cur_axfr_pkt);
-		}
-
-		if (res->_rtt) {
-			LDNS_FREE(res->_rtt);
-		}
-		if (res->_dnssec_anchors) {
-			ldns_rr_list_deep_free(res->_dnssec_anchors);
-		}
-		LDNS_FREE(res);
-	}
-}
-
-ldns_status
-ldns_resolver_search_status(ldns_pkt** pkt,
-		ldns_resolver *r, const  ldns_rdf *name,
-		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
-{
-	ldns_rdf *new_name;
-	ldns_rdf **search_list;
-	size_t i;
-	ldns_status s = LDNS_STATUS_OK;
-	ldns_rdf root_dname = { 1, LDNS_RDF_TYPE_DNAME, (void *)"" };
-
-	if (ldns_dname_absolute(name)) {
-		/* query as-is */
-		return ldns_resolver_query_status(pkt, r, name, t, c, flags);
-	} else if (ldns_resolver_dnsrch(r)) {
-		search_list = ldns_resolver_searchlist(r);
-		for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) {
-			if (i == ldns_resolver_searchlist_count(r)) {
-				new_name = ldns_dname_cat_clone(name,
-						&root_dname);
-			} else {
-				new_name = ldns_dname_cat_clone(name,
-						search_list[i]);
-			}
-
-			s = ldns_resolver_query_status(pkt, r,
-					new_name, t, c, flags);
-			ldns_rdf_free(new_name);
-			if (pkt && *pkt) {
-				if (s == LDNS_STATUS_OK && 
-						ldns_pkt_get_rcode(*pkt) ==
-						LDNS_RCODE_NOERROR) {
-
-					return LDNS_STATUS_OK;
-				}
-				ldns_pkt_free(*pkt);
-				*pkt = NULL;
-			}
-		}
-	}
-	return s;
-}
-
-ldns_pkt *
-ldns_resolver_search(const ldns_resolver *r,const  ldns_rdf *name,
-	ldns_rr_type t, ldns_rr_class c, uint16_t flags)
-{
-	ldns_pkt* pkt = NULL;
-	if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r,
-				name, t, c, flags) != LDNS_STATUS_OK) {
-		ldns_pkt_free(pkt);
-	}
-	return pkt;
-}
-
-ldns_status
-ldns_resolver_query_status(ldns_pkt** pkt,
-		ldns_resolver *r, const ldns_rdf *name,
-		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
-{
-	ldns_rdf *newname;
-	ldns_status status;
-
-	if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) {
-		return ldns_resolver_send(pkt, r, name, t, c, flags);
-	}
-
-	newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r));
-	if (!newname) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	status = ldns_resolver_send(pkt, r, newname, t, c, flags);
-	ldns_rdf_free(newname);
-	return status;
-}
-
-ldns_pkt *
-ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
-	ldns_rr_type t, ldns_rr_class c, uint16_t flags)
-{
-	ldns_pkt* pkt = NULL;
-	if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r,
-				name, t, c, flags) != LDNS_STATUS_OK) {
-		ldns_pkt_free(pkt);
-	}
-	return pkt;
-}
-
-static size_t *
-ldns_resolver_backup_rtt(ldns_resolver *r)
-{
-	size_t *new_rtt;
-	size_t *old_rtt = ldns_resolver_rtt(r);
-
-	if (old_rtt && ldns_resolver_nameserver_count(r)) {
-		new_rtt = LDNS_XMALLOC(size_t
-				, ldns_resolver_nameserver_count(r));
-		memcpy(new_rtt, old_rtt, sizeof(size_t)
-				* ldns_resolver_nameserver_count(r));
-		ldns_resolver_set_rtt(r, new_rtt);
-		return old_rtt;
-	}
-	return NULL;
-}
-
-static void
-ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
-{
-	size_t *cur_rtt = ldns_resolver_rtt(r);
-
-	if (cur_rtt) {
-		LDNS_FREE(cur_rtt);
-	}
-	ldns_resolver_set_rtt(r, old_rtt);
-}
-
-ldns_status
-ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
-				   ldns_pkt *query_pkt)
-{
-	ldns_pkt *answer_pkt = NULL;
-	ldns_status stat = LDNS_STATUS_OK;
-	size_t *rtt;
-
-	stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
-	if (stat != LDNS_STATUS_OK) {
-		if(answer_pkt) {
-			ldns_pkt_free(answer_pkt);
-			answer_pkt = NULL;
-		}
-	} else {
-		/* if tc=1 fall back to EDNS and/or TCP */
-		/* check for tcp first (otherwise we don't care about tc=1) */
-		if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
-			if (ldns_pkt_tc(answer_pkt)) {
-				/* was EDNS0 set? */
-				if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
-					ldns_pkt_set_edns_udp_size(query_pkt
-							, 4096);
-					ldns_pkt_free(answer_pkt);
-					answer_pkt = NULL;
-					/* Nameservers should not become 
-					 * unreachable because fragments are
-					 * dropped (network error). We might
-					 * still have success with TCP.
-					 * Therefore maintain reachability
-					 * statuses of the nameservers by
-					 * backup and restore the rtt list.
-					 */
-					rtt = ldns_resolver_backup_rtt(r);
-					stat = ldns_send(&answer_pkt, r
-							, query_pkt);
-					ldns_resolver_restore_rtt(r, rtt);
-				}
-				/* either way, if it is still truncated, use TCP */
-				if (stat != LDNS_STATUS_OK ||
-				    ldns_pkt_tc(answer_pkt)) {
-					ldns_resolver_set_usevc(r, true);
-					ldns_pkt_free(answer_pkt);
-					stat = ldns_send(&answer_pkt, r, query_pkt);
-					ldns_resolver_set_usevc(r, false);
-				}
-			}
-		}
-	}
-
-	if (answer) {
-		*answer = answer_pkt;
-	}
-
-	return stat;
-}
-
-ldns_status
-ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r,
-                                const ldns_rdf *name, ldns_rr_type t,
-                                ldns_rr_class c, uint16_t flags)
-{
-	struct timeval now;
-	ldns_rr* soa = NULL;
-
-	/* prepare a question pkt from the parameters
-	 * and then send this */
-	if (t == LDNS_RR_TYPE_IXFR) {
-		ldns_rdf *owner_rdf;
-		ldns_rdf *mname_rdf;
-		ldns_rdf *rname_rdf;
-		ldns_rdf *serial_rdf;
-		ldns_rdf *refresh_rdf;
-		ldns_rdf *retry_rdf;
-		ldns_rdf *expire_rdf;
-		ldns_rdf *minimum_rdf;
-		soa = ldns_rr_new();
-
-		if (!soa) {
-			return LDNS_STATUS_ERR;
-		}
-		owner_rdf = ldns_rdf_clone(name);
-		if (!owner_rdf) {
-			ldns_rr_free(soa);
-			return LDNS_STATUS_ERR;
-		}
-		ldns_rr_set_owner(soa, owner_rdf);
-		ldns_rr_set_type(soa, LDNS_RR_TYPE_SOA);
-		ldns_rr_set_class(soa, c);
-		ldns_rr_set_question(soa, false);
-		if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
-			ldns_rr_free(soa);
-			return LDNS_STATUS_ERR;
-		} else	ldns_rr_push_rdf(soa, mname_rdf);
-		if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
-			ldns_rr_free(soa);
-			return LDNS_STATUS_ERR;
-		} else	ldns_rr_push_rdf(soa, rname_rdf);
-		serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, ldns_resolver_get_ixfr_serial(r));
-		if (!serial_rdf) {
-			ldns_rr_free(soa);
-			return LDNS_STATUS_ERR;
-		} else	ldns_rr_push_rdf(soa, serial_rdf);
-		refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-		if (!refresh_rdf) {
-			ldns_rr_free(soa);
-			return LDNS_STATUS_ERR;
-		} else	ldns_rr_push_rdf(soa, refresh_rdf);
-		retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-		if (!retry_rdf) {
-			ldns_rr_free(soa);
-			return LDNS_STATUS_ERR;
-		} else	ldns_rr_push_rdf(soa, retry_rdf);
-		expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-		if (!expire_rdf) {
-			ldns_rr_free(soa);
-			return LDNS_STATUS_ERR;
-		} else	ldns_rr_push_rdf(soa, expire_rdf);
-		minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
-		if (!minimum_rdf) {
-			ldns_rr_free(soa);
-			return LDNS_STATUS_ERR;
-		} else	ldns_rr_push_rdf(soa, minimum_rdf);
-
-		*query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name),
-			c, flags, soa);
-	} else {
-		*query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
-	}
-	if (!*query_pkt) {
-		ldns_rr_free(soa);
-		return LDNS_STATUS_ERR;
-	}
-
-	/* set DO bit if necessary */
-	if (ldns_resolver_dnssec(r)) {
-		if (ldns_resolver_edns_udp_size(r) == 0) {
-			ldns_resolver_set_edns_udp_size(r, 4096);
-		}
-		ldns_pkt_set_edns_do(*query_pkt, true);
-		if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
-			ldns_pkt_set_cd(*query_pkt, true);
-		}
-	}
-
-	/* transfer the udp_edns_size from the resolver to the packet */
-	if (ldns_resolver_edns_udp_size(r) != 0) {
-		ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r));
-	}
-
-	/* set the timestamp */
-	now.tv_sec = time(NULL);
-	now.tv_usec = 0;
-	ldns_pkt_set_timestamp(*query_pkt, now);
-
-
-	if (ldns_resolver_debug(r)) {
-		ldns_pkt_print(stdout, *query_pkt);
-	}
-
-	/* only set the id if it is not set yet */
-	if (ldns_pkt_id(*query_pkt) == 0) {
-		ldns_pkt_set_random_id(*query_pkt);
-	}
-
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
-		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
-{
-	ldns_pkt *query_pkt;
-	ldns_pkt *answer_pkt;
-	ldns_status status;
-
-	assert(r != NULL);
-	assert(name != NULL);
-
-	answer_pkt = NULL;
-
-	/* do all the preprocessing here, then fire of an query to
-	 * the network */
-
-	if (0 == t) {
-		t= LDNS_RR_TYPE_A;
-	}
-	if (0 == c) {
-		c= LDNS_RR_CLASS_IN;
-	}
-	if (0 == ldns_resolver_nameserver_count(r)) {
-		return LDNS_STATUS_RES_NO_NS;
-	}
-	if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
-		return LDNS_STATUS_RES_QUERY;
-	}
-
-	status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
-	                                         t, c, flags);
-	if (status != LDNS_STATUS_OK) {
-		return status;
-	}
-
-	/* if tsig values are set, tsign it */
-	/* TODO: make last 3 arguments optional too? maybe make complete
-	         rr instead of separate values in resolver (and packet)
-	  Jelte
-	  should this go in pkt_prepare?
-	*/
-	if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) {
-#ifdef HAVE_SSL
-		status = ldns_pkt_tsig_sign(query_pkt,
-		                            ldns_resolver_tsig_keyname(r),
-		                            ldns_resolver_tsig_keydata(r),
-		                            300, ldns_resolver_tsig_algorithm(r), NULL);
-		if (status != LDNS_STATUS_OK) {
-			ldns_pkt_free(query_pkt);
-			return LDNS_STATUS_CRYPTO_TSIG_ERR;
-		}
-#else
-		ldns_pkt_free(query_pkt);
-	        return LDNS_STATUS_CRYPTO_TSIG_ERR;
-#endif /* HAVE_SSL */
-	}
-
-	status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
-	ldns_pkt_free(query_pkt);
-
-	/* allows answer to be NULL when not interested in return value */
-	if (answer) {
-		*answer = answer_pkt;
-	}
-	return status;
-}
-
-ldns_rr *
-ldns_axfr_next(ldns_resolver *resolver)
-{
-	ldns_rr *cur_rr;
-	uint8_t *packet_wire;
-	size_t packet_wire_size;
-	ldns_status status;
-
-	/* check if start() has been called */
-	if (!resolver || resolver->_socket == 0) {
-		return NULL;
-	}
-
-	if (resolver->_cur_axfr_pkt) {
-		if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
-			ldns_pkt_free(resolver->_cur_axfr_pkt);
-			resolver->_cur_axfr_pkt = NULL;
-			return ldns_axfr_next(resolver);
-		}
-		cur_rr = ldns_rr_clone(ldns_rr_list_rr(
-					ldns_pkt_answer(resolver->_cur_axfr_pkt),
-					resolver->_axfr_i));
-		resolver->_axfr_i++;
-		if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
-			resolver->_axfr_soa_count++;
-			if (resolver->_axfr_soa_count >= 2) {
-#ifndef USE_WINSOCK
-				close(resolver->_socket);
-#else
-				closesocket(resolver->_socket);
-#endif
-				resolver->_socket = 0;
-				ldns_pkt_free(resolver->_cur_axfr_pkt);
-				resolver->_cur_axfr_pkt = NULL;
-			}
-		}
-		return cur_rr;
-	} else {
-               packet_wire = ldns_tcp_read_wire_timeout(resolver->_socket, &packet_wire_size, resolver->_timeout);
-		if(!packet_wire)
-			return NULL;
-
-		status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
-				     packet_wire_size);
-		LDNS_FREE(packet_wire);
-
-		resolver->_axfr_i = 0;
-		if (status != LDNS_STATUS_OK) {
-			/* TODO: make status return type of this function (...api change) */
-#ifdef STDERR_MSGS
-			fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
-#endif
-
-			/* we must now also close the socket, otherwise subsequent uses of the
-			   same resolver structure will fail because the link is still open or
-			   in an undefined state */
-#ifndef USE_WINSOCK
-			close(resolver->_socket);
-#else
-			closesocket(resolver->_socket);
-#endif
-			resolver->_socket = 0;
-
-			return NULL;
-		} else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
-#ifdef STDERR_MSGS
-			ldns_lookup_table *rcode = ldns_lookup_by_id(
-				ldns_rcodes,(int) ldns_pkt_get_rcode(
-				resolver->_cur_axfr_pkt));
-			if (rcode) {
-				fprintf(stderr, "Error in AXFR: %s\n", 
-						rcode->name);
-			} else {
-				fprintf(stderr, "Error in AXFR: %d\n", 
-						(int) ldns_pkt_get_rcode(
-						resolver->_cur_axfr_pkt));
-			}
-#endif
-
-			/* we must now also close the socket, otherwise subsequent uses of the
-			   same resolver structure will fail because the link is still open or
-			   in an undefined state */
-#ifndef USE_WINSOCK
-			close(resolver->_socket);
-#else
-			closesocket(resolver->_socket);
-#endif
-			resolver->_socket = 0;
-
-			return NULL;
-		} else {
-			return ldns_axfr_next(resolver);
-		}
-
-	}
-
-}
-
-/* this function is needed to abort a transfer that is in progress;
- * without it an aborted transfer will lead to the AXFR code in the
- * library staying in an indetermined state because the socket for the
- * AXFR is never closed
- */
-void
-ldns_axfr_abort(ldns_resolver *resolver)
-{
-	/* Only abort if an actual AXFR is in progress */
-	if (resolver->_socket != 0)
-	{
-#ifndef USE_WINSOCK
-		close(resolver->_socket);
-#else
-		closesocket(resolver->_socket);
-#endif
-		resolver->_socket = 0;
-	}
-}
-
-bool
-ldns_axfr_complete(const ldns_resolver *res)
-{
-	/* complete when soa count is 2? */
-	return res->_axfr_soa_count == 2;
-}
-
-ldns_pkt *
-ldns_axfr_last_pkt(const ldns_resolver *res)
-{
-	return res->_cur_axfr_pkt;
-}
-
-void
-ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial)
-{
-	r->_serial = serial;
-}
-
-uint32_t
-ldns_resolver_get_ixfr_serial(const ldns_resolver *res)
-{
-	return res->_serial;
-}
-
-
-/* random isn't really that good */
-void
-ldns_resolver_nameservers_randomize(ldns_resolver *r)
-{
-	uint16_t i, j;
-	ldns_rdf **ns, *tmpns;
-	size_t *rtt, tmprtt;
-
-	/* should I check for ldns_resolver_random?? */
-	assert(r != NULL);
-
-	ns = ldns_resolver_nameservers(r);
-	rtt = ldns_resolver_rtt(r);
-	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
-		j = ldns_get_random() % ldns_resolver_nameserver_count(r);
-		tmpns = ns[i];
-		ns[i] = ns[j];
-		ns[j] = tmpns;
-		tmprtt = rtt[i];
-		rtt[i] = rtt[j];
-		rtt[j] = tmprtt;
-	}
-	ldns_resolver_set_nameservers(r, ns);
-}
-
diff --git a/src/ldns/rr.c b/src/ldns/rr.c
deleted file mode 100644
index e52ea80..0000000
--- a/src/ldns/rr.c
+++ /dev/null
@@ -1,2705 +0,0 @@
-/* rr.c
- *
- * access functions for ldns_rr -
- * a Net::DNS like library for C
- * LibDNS Team @ NLnet Labs
- *
- * (c) NLnet Labs, 2004-2006
- * See the file LICENSE for the license
- */
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <strings.h>
-#include <limits.h>
-
-#include <errno.h>
-
-#define LDNS_SYNTAX_DATALEN 16
-#define LDNS_TTL_DATALEN    21
-#define LDNS_RRLIST_INIT    8
-
-ldns_rr *
-ldns_rr_new(void)
-{
-	ldns_rr *rr;
-	rr = LDNS_MALLOC(ldns_rr);
-        if (!rr) {
-                return NULL;
-	}
-
-	ldns_rr_set_owner(rr, NULL);
-	ldns_rr_set_question(rr, false);
-	ldns_rr_set_rd_count(rr, 0);
-	rr->_rdata_fields = NULL;
-	ldns_rr_set_class(rr, LDNS_RR_CLASS_IN);
-	ldns_rr_set_ttl(rr, LDNS_DEFAULT_TTL);
-        return rr;
-}
-
-ldns_rr *
-ldns_rr_new_frm_type(ldns_rr_type t)
-{
-	ldns_rr *rr;
-	const ldns_rr_descriptor *desc;
-	size_t i;
-
-	rr = LDNS_MALLOC(ldns_rr);
-        if (!rr) {
-                return NULL;
-	}
-
-	desc = ldns_rr_descript(t);
-
-	rr->_rdata_fields = LDNS_XMALLOC(ldns_rdf *, ldns_rr_descriptor_minimum(desc));
-        if(!rr->_rdata_fields) {
-                LDNS_FREE(rr);
-                return NULL;
-        }
-	for (i = 0; i < ldns_rr_descriptor_minimum(desc); i++) {
-		rr->_rdata_fields[i] = NULL;
-	}
-
-	ldns_rr_set_owner(rr, NULL);
-	ldns_rr_set_question(rr, false);
-	/* set the count to minimum */
-	ldns_rr_set_rd_count(rr, ldns_rr_descriptor_minimum(desc));
-	ldns_rr_set_class(rr, LDNS_RR_CLASS_IN);
-	ldns_rr_set_ttl(rr, LDNS_DEFAULT_TTL);
-	ldns_rr_set_type(rr, t);
-	return rr;
-}
-
-void
-ldns_rr_free(ldns_rr *rr)
-{
-	size_t i;
-	if (rr) {
-		if (ldns_rr_owner(rr)) {
-			ldns_rdf_deep_free(ldns_rr_owner(rr));
-		}
-		for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-			ldns_rdf_deep_free(ldns_rr_rdf(rr, i));
-		}
-		LDNS_FREE(rr->_rdata_fields);
-		LDNS_FREE(rr);
-	}
-}
-
-/* Syntactic sugar for ldns_rr_new_frm_str_internal */
-INLINE bool
-ldns_rdf_type_maybe_quoted(ldns_rdf_type rdf_type)
-{
-	return  rdf_type == LDNS_RDF_TYPE_STR ||
-		rdf_type == LDNS_RDF_TYPE_LONG_STR;
-}
-
-/*
- * trailing spaces are allowed
- * leading spaces are not allowed
- * allow ttl to be optional
- * class is optional too
- * if ttl is missing, and default_ttl is 0, use DEF_TTL
- * allow ttl to be written as 1d3h
- * So the RR should look like. e.g.
- * miek.nl. 3600 IN MX 10 elektron.atoom.net
- * or
- * miek.nl. 1h IN MX 10 elektron.atoom.net
- * or
- * miek.nl. IN MX 10 elektron.atoom.net
- */
-static ldns_status
-ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
-                             uint32_t default_ttl, ldns_rdf *origin,
-		             ldns_rdf **prev, bool question)
-{
-	ldns_rr *new;
-	const ldns_rr_descriptor *desc;
-	ldns_rr_type rr_type;
-	ldns_buffer *rr_buf = NULL;
-	ldns_buffer *rd_buf = NULL;
-	uint32_t ttl_val;
-	char  *owner = NULL;
-	char  *ttl = NULL;
-	ldns_rr_class clas_val;
-	char  *clas = NULL;
-	char  *type = NULL;
-	char  *rdata = NULL;
-	char  *rd = NULL;
-	char  *xtok = NULL; /* For RDF types with spaces (i.e. extra tokens) */
-	size_t rd_strlen;
-	const char *delimiters;
-	ssize_t c;
-	ldns_rdf *owner_dname;
-        const char* endptr;
-        int was_unknown_rr_format = 0;
-	ldns_status status = LDNS_STATUS_OK;
-
-	/* used for types with unknown number of rdatas */
-	bool done;
-	bool quoted;
-
-	ldns_rdf *r = NULL;
-	uint16_t r_cnt;
-	uint16_t r_min;
-	uint16_t r_max;
-        size_t pre_data_pos;
-
-	uint16_t hex_data_size;
-	char *hex_data_str = NULL;
-	uint16_t cur_hex_data_size;
-	size_t hex_pos = 0;
-	uint8_t *hex_data = NULL;
-
-	new = ldns_rr_new();
-
-	owner = LDNS_XMALLOC(char, LDNS_MAX_DOMAINLEN + 1);
-	ttl = LDNS_XMALLOC(char, LDNS_TTL_DATALEN);
-	clas = LDNS_XMALLOC(char, LDNS_SYNTAX_DATALEN);
-	rdata = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN + 1);
-	rr_buf = LDNS_MALLOC(ldns_buffer);
-	rd_buf = LDNS_MALLOC(ldns_buffer);
-	rd = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
-	xtok = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
-	if (rr_buf) {
-		rr_buf->_data = NULL;
-	}
-	if (rd_buf) {
-		rd_buf->_data = NULL;
-	}
-	if (!new || !owner || !ttl || !clas || !rdata ||
-			!rr_buf || !rd_buf || !rd || !xtok) {
-
-		goto memerror;
-	}
-
-	ldns_buffer_new_frm_data(rr_buf, (char*)str, strlen(str));
-
-	/* split the rr in its parts -1 signals trouble */
-	if (ldns_bget_token(rr_buf, owner, "\t\n ", LDNS_MAX_DOMAINLEN) == -1){
-
-		status = LDNS_STATUS_SYNTAX_ERR;
-		goto error;
-	}
-
-	if (ldns_bget_token(rr_buf, ttl, "\t\n ", LDNS_TTL_DATALEN) == -1) {
-
-		status = LDNS_STATUS_SYNTAX_TTL_ERR;
-		goto error;
-	}
-	ttl_val = (uint32_t) ldns_str2period(ttl, &endptr);
-
-	if (strlen(ttl) > 0 && !isdigit((int) ttl[0])) {
-		/* ah, it's not there or something */
-		if (default_ttl == 0) {
-			ttl_val = LDNS_DEFAULT_TTL;
-		} else {
-			ttl_val = default_ttl;
-		}
-		/* we not ASSUMING the TTL is missing and that
-		 * the rest of the RR is still there. That is
-		 * CLASS TYPE RDATA
-		 * so ttl value we read is actually the class
-		 */
-		clas_val = ldns_get_rr_class_by_name(ttl);
-		/* class can be left out too, assume IN, current
-		 * token must be type
-		 */
-		if (clas_val == 0) {
-			clas_val = LDNS_RR_CLASS_IN;
-			type = LDNS_XMALLOC(char, strlen(ttl) + 1);
-			if (!type) {
-				goto memerror;
-			}
-			strncpy(type, ttl, strlen(ttl) + 1);
-		}
-	} else {
-		if (-1 == ldns_bget_token(
-				rr_buf, clas, "\t\n ", LDNS_SYNTAX_DATALEN)) {
-
-			status = LDNS_STATUS_SYNTAX_CLASS_ERR;
-			goto error;
-		}
-		clas_val = ldns_get_rr_class_by_name(clas);
-		/* class can be left out too, assume IN, current
-		 * token must be type
-		 */
-		if (clas_val == 0) {
-			clas_val = LDNS_RR_CLASS_IN;
-			type = LDNS_XMALLOC(char, strlen(clas) + 1);
-			if (!type) {
-				goto memerror;
-			}
-			strncpy(type, clas, strlen(clas) + 1);
-		}
-	}
-	/* the rest should still be waiting for us */
-
-	if (!type) {
-		type = LDNS_XMALLOC(char, LDNS_SYNTAX_DATALEN);
-		if (!type) {
-			goto memerror;
-		}
-		if (-1 == ldns_bget_token(
-				rr_buf, type, "\t\n ", LDNS_SYNTAX_DATALEN)) {
-
-			status = LDNS_STATUS_SYNTAX_TYPE_ERR;
-			goto error;
-		}
-	}
-
-	if (ldns_bget_token(rr_buf, rdata, "\0", LDNS_MAX_PACKETLEN) == -1) {
-		/* apparently we are done, and it's only a question RR
-		 * so do not set status and go to ldnserror here
-		 */
-	}
-	ldns_buffer_new_frm_data(rd_buf, rdata, strlen(rdata));
-
-	if (strlen(owner) <= 1 && strncmp(owner, "@", 1) == 0) {
-		if (origin) {
-			ldns_rr_set_owner(new, ldns_rdf_clone(origin));
-		} else if (prev && *prev) {
-			ldns_rr_set_owner(new, ldns_rdf_clone(*prev));
-		} else {
-			/* default to root */
-			ldns_rr_set_owner(new, ldns_dname_new_frm_str("."));
-		}
-
-		/* @ also overrides prev */
-		if (prev) {
-			ldns_rdf_deep_free(*prev);
-			*prev = ldns_rdf_clone(ldns_rr_owner(new));
-			if (!*prev) {
-				goto memerror;
-			}
-		}
-	} else {
-		if (strlen(owner) == 0) {
-			/* no ownername was given, try prev, if that fails
-			 * origin, else default to root */
-			if (prev && *prev) {
-				ldns_rr_set_owner(new, ldns_rdf_clone(*prev));
-			} else if (origin) {
-				ldns_rr_set_owner(new, ldns_rdf_clone(origin));
-			} else {
-				ldns_rr_set_owner(new,
-						ldns_dname_new_frm_str("."));
-			}
-			if(!ldns_rr_owner(new)) {
-				goto memerror;
-			}
-		} else {
-			owner_dname = ldns_dname_new_frm_str(owner);
-			if (!owner_dname) {
-				status = LDNS_STATUS_SYNTAX_ERR;
-				goto error;
-			}
-
-			ldns_rr_set_owner(new, owner_dname);
-			if (!ldns_dname_str_absolute(owner) && origin) {
-				if(ldns_dname_cat(ldns_rr_owner(new), origin)
-						!= LDNS_STATUS_OK) {
-
-					status = LDNS_STATUS_SYNTAX_ERR;
-					goto error;
-				}
-			}
-			if (prev) {
-				ldns_rdf_deep_free(*prev);
-				*prev = ldns_rdf_clone(ldns_rr_owner(new));
-				if (!*prev) {
-					goto error;
-				}
-			}
-		}
-	}
-	LDNS_FREE(owner);
-
-	ldns_rr_set_question(new, question);
-
-	ldns_rr_set_ttl(new, ttl_val);
-	LDNS_FREE(ttl);
-
-	ldns_rr_set_class(new, clas_val);
-	LDNS_FREE(clas);
-
-	rr_type = ldns_get_rr_type_by_name(type);
-	LDNS_FREE(type);
-
-	desc = ldns_rr_descript((uint16_t)rr_type);
-	ldns_rr_set_type(new, rr_type);
-	if (desc) {
-		/* only the rdata remains */
-		r_max = ldns_rr_descriptor_maximum(desc);
-		r_min = ldns_rr_descriptor_minimum(desc);
-	} else {
-		r_min = 0;
-		r_max = 1;
-	}
-
-	for (done = false, r_cnt = 0; !done && r_cnt < r_max; r_cnt++) {
-		quoted = false;
-
-		switch (ldns_rr_descriptor_field_type(desc, r_cnt)) {
-		case LDNS_RDF_TYPE_B64        :
-		case LDNS_RDF_TYPE_HEX        : /* These rdf types may con- */
-		case LDNS_RDF_TYPE_LOC        : /* tain whitespace, only if */
-		case LDNS_RDF_TYPE_WKS        : /* it is the last rd field. */
-		case LDNS_RDF_TYPE_IPSECKEY   :
-		case LDNS_RDF_TYPE_NSEC       :	if (r_cnt == r_max - 1) {
-							delimiters = "\n";
-							break;
-						}
-		default                       :	delimiters = "\n\t "; 
-		}
-
-		if (ldns_rdf_type_maybe_quoted(
-				ldns_rr_descriptor_field_type(
-				desc, r_cnt)) &&
-				ldns_buffer_remaining(rd_buf) > 0){
-
-			/* skip spaces */
-			while (*(ldns_buffer_current(rd_buf)) == ' ') {
-				ldns_buffer_skip(rd_buf, 1);
-			}
-
-			if (*(ldns_buffer_current(rd_buf)) == '\"') {
-				delimiters = "\"\0";
-				ldns_buffer_skip(rd_buf, 1);
-				quoted = true;
-			}
-		}
-
-		/* because number of fields can be variable, we can't rely on
-		 * _maximum() only
-		 */
-
-		/* skip spaces */
-		while (ldns_buffer_position(rd_buf) < ldns_buffer_limit(rd_buf)
-				&& *(ldns_buffer_current(rd_buf)) == ' '
-				&& !quoted) {
-
-			ldns_buffer_skip(rd_buf, 1);
-		}
-
-		pre_data_pos = ldns_buffer_position(rd_buf);
-		if (-1 == (c = ldns_bget_token(
-				rd_buf, rd, delimiters, LDNS_MAX_RDFLEN))) {
-
-			done = true;
-			break;
-		}
-		/* hmmz, rfc3597 specifies that any type can be represented 
-		 * with \# method, which can contain spaces...
-		 * it does specify size though...
-		 */
-		rd_strlen = strlen(rd);
-
-		/* unknown RR data */
-		if (strncmp(rd, "\\#", 2) == 0 && !quoted &&
-				(rd_strlen == 2 || rd[2]==' ')) {
-
-			was_unknown_rr_format = 1;
-			/* go back to before \#
-			 * and skip it while setting delimiters better
-			 */
-			ldns_buffer_set_position(rd_buf, pre_data_pos);
-			delimiters = "\n\t ";
-			(void)ldns_bget_token(rd_buf, rd,
-					delimiters, LDNS_MAX_RDFLEN);
-			/* read rdata octet length */
-			c = ldns_bget_token(rd_buf, rd,
-					delimiters, LDNS_MAX_RDFLEN);
-			if (c == -1) {
-				/* something goes very wrong here */
-				status = LDNS_STATUS_SYNTAX_RDATA_ERR;
-				goto error;
-			}
-			hex_data_size = (uint16_t) atoi(rd);
-			/* copy hex chars into hex str (2 chars per byte) */
-			hex_data_str = LDNS_XMALLOC(char, 2*hex_data_size + 1);
-			if (!hex_data_str) {
-				/* malloc error */
-				goto memerror;
-			}
-			cur_hex_data_size = 0;
-			while(cur_hex_data_size < 2 * hex_data_size) {
-				c = ldns_bget_token(rd_buf, rd,
-						delimiters, LDNS_MAX_RDFLEN);
-				if (c != -1) {
-					rd_strlen = strlen(rd);
-				}
-				if (c == -1 || 
-				    (size_t)cur_hex_data_size + rd_strlen >
-				    2 * (size_t)hex_data_size) {
-
-					status = LDNS_STATUS_SYNTAX_RDATA_ERR;
-					goto error;
-				}
-				strncpy(hex_data_str + cur_hex_data_size, rd,
-						rd_strlen);
-
-				cur_hex_data_size += rd_strlen;
-			}
-			hex_data_str[cur_hex_data_size] = '\0';
-
-			/* correct the rdf type */
-			/* if *we* know the type, interpret it as wireformat */
-			if (desc) {
-				hex_pos = 0;
-				hex_data =
-					LDNS_XMALLOC(uint8_t, hex_data_size+2);
-
-				if (!hex_data) {
-					goto memerror;
-				}
-				ldns_write_uint16(hex_data, hex_data_size);
-				ldns_hexstring_to_data(
-						hex_data + 2, hex_data_str);
-				status = ldns_wire2rdf(new, hex_data,
-						hex_data_size + 2, &hex_pos);
-				if (status != LDNS_STATUS_OK) {
-					goto error;
-				}
-				LDNS_FREE(hex_data);
-			} else {
-				r = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_HEX,
-						hex_data_str);
-				if (!r) {
-					goto memerror;
-				}
-				ldns_rdf_set_type(r, LDNS_RDF_TYPE_UNKNOWN);
-				if (!ldns_rr_push_rdf(new, r)) {
-					goto memerror;
-				}
-			}
-			LDNS_FREE(hex_data_str);
-
-		} else if(rd_strlen > 0 || quoted) {
-			/* Normal RR */
-			switch(ldns_rr_descriptor_field_type(desc, r_cnt)) {
-
-			case LDNS_RDF_TYPE_HEX:
-			case LDNS_RDF_TYPE_B64:
-				/* When this is the last rdata field, then the
-				 * rest should be read in (cause then these
-				 * rdf types may contain spaces).
-				 */
-				if (r_cnt == r_max - 1) {
-					c = ldns_bget_token(rd_buf, xtok,
-							"\n", LDNS_MAX_RDFLEN);
-					if (c != -1) {
-						(void) strncat(rd, xtok,
-							LDNS_MAX_RDFLEN -
-							strlen(rd) - 1);
-					}
-				}
-				r = ldns_rdf_new_frm_str(
-						ldns_rr_descriptor_field_type(
-							desc, r_cnt), rd);
-				break;
-
-			case LDNS_RDF_TYPE_HIP:
-				/*
-				 * In presentation format this RDATA type has
-				 * three tokens: An algorithm byte, then a
-				 * variable length HIT (in hexbytes) and then
-				 * a variable length Public Key (in base64).
-				 *
-				 * We have just read the algorithm, so we need
-				 * two more tokens: HIT and Public Key.
-				 */
-				do {
-					/* Read and append HIT */
-					if (ldns_bget_token(rd_buf,
-							xtok, delimiters,
-							LDNS_MAX_RDFLEN) == -1)
-						break;
-
-					(void) strncat(rd, " ",
-							LDNS_MAX_RDFLEN -
-							strlen(rd) - 1);
-					(void) strncat(rd, xtok,
-							LDNS_MAX_RDFLEN -
-							strlen(rd) - 1);
-
-					/* Read and append Public Key*/
-					if (ldns_bget_token(rd_buf,
-							xtok, delimiters,
-							LDNS_MAX_RDFLEN) == -1)
-						break;
-
-					(void) strncat(rd, " ",
-							LDNS_MAX_RDFLEN -
-							strlen(rd) - 1);
-					(void) strncat(rd, xtok,
-							LDNS_MAX_RDFLEN -
-							strlen(rd) - 1);
-				} while (false);
-
-				r = ldns_rdf_new_frm_str(
-						ldns_rr_descriptor_field_type(
-							desc, r_cnt), rd);
-				break;
-
-			case LDNS_RDF_TYPE_DNAME:
-				r = ldns_rdf_new_frm_str(
-						ldns_rr_descriptor_field_type(
-							desc, r_cnt), rd);
-
-				/* check if the origin should be used
-				 * or concatenated
-				 */
-				if (r && ldns_rdf_size(r) > 1 &&
-						ldns_rdf_data(r)[0] == 1 &&
-						ldns_rdf_data(r)[1] == '@') {
-
-					ldns_rdf_deep_free(r);
-
-					r = origin ? ldns_rdf_clone(origin)
-
-					  : ( rr_type == LDNS_RR_TYPE_SOA ?
-
-					      ldns_rdf_clone(
-						      ldns_rr_owner(new))
-
-					    : ldns_rdf_new_frm_str(
-						    LDNS_RDF_TYPE_DNAME, ".")
-					    );
-
-				} else if (r && rd_strlen >= 1 && origin &&
-						!ldns_dname_str_absolute(rd)) {
-
-					status = ldns_dname_cat(r, origin);
-					if (status != LDNS_STATUS_OK) {
-						goto error;
-					}
-				}
-				break;
-			default:
-				r = ldns_rdf_new_frm_str(
-						ldns_rr_descriptor_field_type(
-							desc, r_cnt), rd);
-				break;
-			}
-			if (!r) {
-				status = LDNS_STATUS_SYNTAX_RDATA_ERR;
-				goto error;
-			}
-			ldns_rr_push_rdf(new, r);
-		}
-		if (quoted) {
-			if (ldns_buffer_available(rd_buf, 1)) {
-				ldns_buffer_skip(rd_buf, 1);
-			} else {
-				done = true;
-			}
-		}
-
-	} /* for (done = false, r_cnt = 0; !done && r_cnt < r_max; r_cnt++) */
-	LDNS_FREE(rd);
-	LDNS_FREE(xtok);
-	ldns_buffer_free(rd_buf);
-	ldns_buffer_free(rr_buf);
-	LDNS_FREE(rdata);
-
-	if (!question && desc && !was_unknown_rr_format &&
-			ldns_rr_rd_count(new) < r_min) {
-
-		ldns_rr_free(new);
-		return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
-	}
-
-	if (newrr) {
-		*newrr = new;
-	} else {
-		/* Maybe the caller just wanted to see if it would parse? */
-		ldns_rr_free(new);
-	}
-	return LDNS_STATUS_OK;
-
-memerror:
-	status = LDNS_STATUS_MEM_ERR;
-error:
-	if (rd_buf && rd_buf->_data) {
-		ldns_buffer_free(rd_buf);
-	} else {
-		LDNS_FREE(rd_buf);
-	}
-	if (rr_buf && rr_buf->_data) {
-		ldns_buffer_free(rr_buf);
-	} else {
-		LDNS_FREE(rr_buf);
-	}
-	LDNS_FREE(type);
-	LDNS_FREE(owner);
-	LDNS_FREE(ttl);
-	LDNS_FREE(clas);
-	LDNS_FREE(hex_data);
-	LDNS_FREE(hex_data_str);
-	LDNS_FREE(xtok);
-	LDNS_FREE(rd);
-	LDNS_FREE(rdata);
-	ldns_rr_free(new);
-	return status;
-}
-
-ldns_status
-ldns_rr_new_frm_str(ldns_rr **newrr, const char *str,
-                    uint32_t default_ttl, ldns_rdf *origin,
-		    ldns_rdf **prev)
-{
-	return ldns_rr_new_frm_str_internal(newrr,
-	                                    str,
-	                                    default_ttl,
-	                                    origin,
-	                                    prev,
-	                                    false);
-}
-
-ldns_status
-ldns_rr_new_question_frm_str(ldns_rr **newrr, const char *str,
-                             ldns_rdf *origin, ldns_rdf **prev)
-{
-	return ldns_rr_new_frm_str_internal(newrr,
-	                                    str,
-	                                    0,
-	                                    origin,
-	                                    prev,
-	                                    true);
-}
-
-/* Strip whitespace from the start and the end of <line>.  */
-static char *
-ldns_strip_ws(char *line)
-{
-	char *s = line, *e;
-
-	for (s = line; *s && isspace(*s); s++)
-		;
-
-	for (e = strchr(s, 0); e > s+2 && isspace(e[-1]) && e[-2] != '\\'; e--)
-		;
-	*e = 0;
-
-	return s;
-}
-
-ldns_status
-ldns_rr_new_frm_fp(ldns_rr **newrr, FILE *fp, uint32_t *ttl, ldns_rdf **origin, ldns_rdf **prev)
-{
-	return ldns_rr_new_frm_fp_l(newrr, fp, ttl, origin, prev, NULL);
-}
-
-ldns_status
-ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr)
-{
-	char *line;
-	const char *endptr;  /* unused */
-	ldns_rr *rr;
-	uint32_t ttl;
-	ldns_rdf *tmp;
-	ldns_status s;
-	ssize_t size;
-
-	if (default_ttl) {
-		ttl = *default_ttl;
-	} else {
-		ttl = 0;
-	}
-
-	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
-	if (!line) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	/* read an entire line in from the file */
-	if ((size = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, LDNS_MAX_LINELEN, line_nr)) == -1) {
-		LDNS_FREE(line);
-		/* if last line was empty, we are now at feof, which is not
-		 * always a parse error (happens when for instance last line
-		 * was a comment)
-		 */
-		return LDNS_STATUS_SYNTAX_ERR;
-	}
-
-	/* we can have the situation, where we've read ok, but still got
-	 * no bytes to play with, in this case size is 0
-	 */
-	if (size == 0) {
-		LDNS_FREE(line);
-		return LDNS_STATUS_SYNTAX_EMPTY;
-	}
-
-	if (strncmp(line, "$ORIGIN", 7) == 0 && isspace(line[7])) {
-		if (*origin) {
-			ldns_rdf_deep_free(*origin);
-			*origin = NULL;
-		}
-		tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME,
-				ldns_strip_ws(line + 8));
-		if (!tmp) {
-			/* could not parse what next to $ORIGIN */
-			LDNS_FREE(line);
-			return LDNS_STATUS_SYNTAX_DNAME_ERR;
-		}
-		*origin = tmp;
-		s = LDNS_STATUS_SYNTAX_ORIGIN;
-	} else if (strncmp(line, "$TTL", 4) == 0 && isspace(line[4])) {
-		if (default_ttl) {
-			*default_ttl = ldns_str2period(
-					ldns_strip_ws(line + 5), &endptr);
-		}
-		s = LDNS_STATUS_SYNTAX_TTL;
-	} else if (strncmp(line, "$INCLUDE", 8) == 0) {
-		s = LDNS_STATUS_SYNTAX_INCLUDE;
-	} else if (!*ldns_strip_ws(line)) {
-		LDNS_FREE(line);
-		return LDNS_STATUS_SYNTAX_EMPTY;
-	} else {
-		if (origin && *origin) {
-			s = ldns_rr_new_frm_str(&rr, (const char*) line, ttl, *origin, prev);
-		} else {
-			s = ldns_rr_new_frm_str(&rr, (const char*) line, ttl, NULL, prev);
-		}
-	}
-	LDNS_FREE(line);
-	if (s == LDNS_STATUS_OK) {
-		if (newrr) {
-			*newrr = rr;
-		} else {
-			/* Just testing if it would parse? */
-			ldns_rr_free(rr);
-		}
-	}
-	return s;
-}
-
-void
-ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
-{
-	rr->_owner = owner;
-}
-
-void
-ldns_rr_set_question(ldns_rr *rr, bool question)
-{
-   rr->_rr_question = question;
-}
-
-void
-ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
-{
-	rr->_ttl = ttl;
-}
-
-void
-ldns_rr_set_rd_count(ldns_rr *rr, size_t count)
-{
-	rr->_rd_count = count;
-}
-
-void
-ldns_rr_set_type(ldns_rr *rr, ldns_rr_type rr_type)
-{
-	rr->_rr_type = rr_type;
-}
-
-void
-ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class)
-{
-	rr->_rr_class = rr_class;
-}
-
-ldns_rdf *
-ldns_rr_set_rdf(ldns_rr *rr, const ldns_rdf *f, size_t position)
-{
-	size_t rd_count;
-	ldns_rdf *pop;
-
-	rd_count = ldns_rr_rd_count(rr);
-	if (position < rd_count) {
-		/* dicard the old one */
-		pop = rr->_rdata_fields[position];
-		rr->_rdata_fields[position] = (ldns_rdf*)f;
-		return pop;
-	} else {
-		return NULL;
-	}
-}
-
-bool
-ldns_rr_push_rdf(ldns_rr *rr, const ldns_rdf *f)
-{
-	size_t rd_count;
-	ldns_rdf **rdata_fields;
-
-	rd_count = ldns_rr_rd_count(rr);
-
-	/* grow the array */
-	rdata_fields = LDNS_XREALLOC(
-		rr->_rdata_fields, ldns_rdf *, rd_count + 1);
-	if (!rdata_fields) {
-		return false;
-	}
-
-	/* add the new member */
-	rr->_rdata_fields = rdata_fields;
-	rr->_rdata_fields[rd_count] = (ldns_rdf*)f;
-
-	ldns_rr_set_rd_count(rr, rd_count + 1);
-	return true;
-}
-
-ldns_rdf *
-ldns_rr_pop_rdf(ldns_rr *rr)
-{
-	size_t rd_count;
-	ldns_rdf *pop;
-	ldns_rdf** newrd;
-
-	rd_count = ldns_rr_rd_count(rr);
-
-	if (rd_count == 0) {
-		return NULL;
-	}
-
-	pop = rr->_rdata_fields[rd_count - 1];
-
-	/* try to shrink the array */
-	if(rd_count > 1) {
-		newrd = LDNS_XREALLOC(
-			rr->_rdata_fields, ldns_rdf *, rd_count - 1);
-		if(newrd)
-			rr->_rdata_fields = newrd;
-	} else {
-		LDNS_FREE(rr->_rdata_fields);
-	}
-
-	ldns_rr_set_rd_count(rr, rd_count - 1);
-	return pop;
-}
-
-ldns_rdf *
-ldns_rr_rdf(const ldns_rr *rr, size_t nr)
-{
-	if (rr && nr < ldns_rr_rd_count(rr)) {
-		return rr->_rdata_fields[nr];
-	} else {
-		return NULL;
-	}
-}
-
-ldns_rdf *
-ldns_rr_owner(const ldns_rr *rr)
-{
-	return rr->_owner;
-}
-
-bool
-ldns_rr_is_question(const ldns_rr *rr)
-{
-   return rr->_rr_question;
-}
-
-uint32_t
-ldns_rr_ttl(const ldns_rr *rr)
-{
-	return rr->_ttl;
-}
-
-size_t
-ldns_rr_rd_count(const ldns_rr *rr)
-{
-	return rr->_rd_count;
-}
-
-ldns_rr_type
-ldns_rr_get_type(const ldns_rr *rr)
-{
-        return rr->_rr_type;
-}
-
-ldns_rr_class
-ldns_rr_get_class(const ldns_rr *rr)
-{
-        return rr->_rr_class;
-}
-
-/* rr_lists */
-
-size_t
-ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
-{
-	if (rr_list) {
-		return rr_list->_rr_count;
-	} else {
-		return 0;
-	}
-}
-
-ldns_rr *
-ldns_rr_list_set_rr(ldns_rr_list *rr_list, const ldns_rr *r, size_t count)
-{
-	ldns_rr *old;
-
-	if (count > ldns_rr_list_rr_count(rr_list)) {
-		return NULL;
-	}
-
-	old = ldns_rr_list_rr(rr_list, count);
-
-	/* overwrite old's pointer */
-	rr_list->_rrs[count] = (ldns_rr*)r;
-	return old;
-}
-
-void
-ldns_rr_list_set_rr_count(ldns_rr_list *rr_list, size_t count)
-{
-	assert(count <= rr_list->_rr_capacity);
-	rr_list->_rr_count = count;
-}
-
-ldns_rr *
-ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
-{
-	if (nr < ldns_rr_list_rr_count(rr_list)) {
-		return rr_list->_rrs[nr];
-	} else {
-		return NULL;
-	}
-}
-
-ldns_rr_list *
-ldns_rr_list_new(void)
-{
-	ldns_rr_list *rr_list = LDNS_MALLOC(ldns_rr_list);
-        if(!rr_list) return NULL;
-	rr_list->_rr_count = 0;
-	rr_list->_rr_capacity = 0;
-	rr_list->_rrs = NULL;
-	return rr_list;
-}
-
-void
-ldns_rr_list_free(ldns_rr_list *rr_list)
-{
-	if (rr_list) {
-		LDNS_FREE(rr_list->_rrs);
-		LDNS_FREE(rr_list);
-	}
-}
-
-void
-ldns_rr_list_deep_free(ldns_rr_list *rr_list)
-{
-	size_t i;
-
-	if (rr_list) {
-		for (i=0; i < ldns_rr_list_rr_count(rr_list); i++) {
-			ldns_rr_free(ldns_rr_list_rr(rr_list, i));
-		}
-		LDNS_FREE(rr_list->_rrs);
-		LDNS_FREE(rr_list);
-	}
-}
-
-
-/* add right to left. So we modify *left! */
-bool
-ldns_rr_list_cat(ldns_rr_list *left, ldns_rr_list *right)
-{
-	size_t r_rr_count;
-	size_t i;
-
-	if (!left) {
-		return false;
-	}
-
-	if (right) {
-		r_rr_count = ldns_rr_list_rr_count(right);
-	} else {
-		r_rr_count = 0;
-	}
-
-	/* push right to left */
-	for(i = 0; i < r_rr_count; i++) {
-		ldns_rr_list_push_rr(left, ldns_rr_list_rr(right, i));
-	}
-	return true;
-}
-
-ldns_rr_list *
-ldns_rr_list_cat_clone(ldns_rr_list *left, ldns_rr_list *right)
-{
-	size_t l_rr_count;
-	size_t r_rr_count;
-	size_t i;
-	ldns_rr_list *cat;
-
-	if (left) {
-		l_rr_count = ldns_rr_list_rr_count(left);
-	} else {
-		return ldns_rr_list_clone(right);
-	}
-
-	if (right) {
-		r_rr_count = ldns_rr_list_rr_count(right);
-	} else {
-		r_rr_count = 0;
-	}
-
-	cat = ldns_rr_list_new();
-
-	if (!cat) {
-		return NULL;
-	}
-
-	/* left */
-	for(i = 0; i < l_rr_count; i++) {
-		ldns_rr_list_push_rr(cat,
-				ldns_rr_clone(ldns_rr_list_rr(left, i)));
-	}
-	/* right */
-	for(i = 0; i < r_rr_count; i++) {
-		ldns_rr_list_push_rr(cat,
-				ldns_rr_clone(ldns_rr_list_rr(right, i)));
-	}
-	return cat;
-}
-
-ldns_rr_list *
-ldns_rr_list_subtype_by_rdf(ldns_rr_list *l, ldns_rdf *r, size_t pos)
-{
-	size_t i;
-	ldns_rr_list *subtyped;
-	ldns_rdf *list_rdf;
-
-	subtyped = ldns_rr_list_new();
-
-	for(i = 0; i < ldns_rr_list_rr_count(l); i++) {
-		list_rdf = ldns_rr_rdf(
-			ldns_rr_list_rr(l, i),
-			pos);
-		if (!list_rdf) {
-			/* pos is too large or any other error */
-			ldns_rr_list_deep_free(subtyped);
-			return NULL;
-		}
-
-		if (ldns_rdf_compare(list_rdf, r) == 0) {
-			/* a match */
-			ldns_rr_list_push_rr(subtyped,
-					ldns_rr_clone(ldns_rr_list_rr(l, i)));
-		}
-	}
-
-	if (ldns_rr_list_rr_count(subtyped) > 0) {
-		return subtyped;
-	} else {
-		ldns_rr_list_free(subtyped);
-		return NULL;
-	}
-}
-
-bool
-ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
-{
-	size_t rr_count;
-	size_t cap;
-
-	rr_count = ldns_rr_list_rr_count(rr_list);
-	cap = rr_list->_rr_capacity;
-
-	/* grow the array */
-	if(rr_count+1 > cap) {
-		ldns_rr **rrs;
-
-		if(cap == 0)
-			cap = LDNS_RRLIST_INIT;  /* initial list size */
-		else	cap *= 2;
-		rrs = LDNS_XREALLOC(rr_list->_rrs, ldns_rr *, cap);
-		if (!rrs) {
-			return false;
-		}
-		rr_list->_rrs = rrs;
-		rr_list->_rr_capacity = cap;
-	}
-
-	/* add the new member */
-	rr_list->_rrs[rr_count] = (ldns_rr*)rr;
-
-	ldns_rr_list_set_rr_count(rr_list, rr_count + 1);
-	return true;
-}
-
-bool
-ldns_rr_list_push_rr_list(ldns_rr_list *rr_list, const ldns_rr_list *push_list)
-{
-	size_t i;
-
-	for(i = 0; i < ldns_rr_list_rr_count(push_list); i++) {
-		if (!ldns_rr_list_push_rr(rr_list,
-				ldns_rr_list_rr(push_list, i))) {
-			return false;
-		}
-	}
-	return true;
-}
-
-ldns_rr *
-ldns_rr_list_pop_rr(ldns_rr_list *rr_list)
-{
-	size_t rr_count;
-	size_t cap;
-	ldns_rr *pop;
-
-	rr_count = ldns_rr_list_rr_count(rr_list);
-
-	if (rr_count == 0) {
-		return NULL;
-	}
-
-	cap = rr_list->_rr_capacity;
-	pop = ldns_rr_list_rr(rr_list, rr_count - 1);
-
-	/* shrink the array */
-	if(cap > LDNS_RRLIST_INIT && rr_count-1 <= cap/2) {
-                ldns_rr** a;
-		cap /= 2;
-                a = LDNS_XREALLOC(rr_list->_rrs, ldns_rr *, cap);
-                if(a) {
-		        rr_list->_rrs = a;
-		        rr_list->_rr_capacity = cap;
-                }
-	}
-
-	ldns_rr_list_set_rr_count(rr_list, rr_count - 1);
-
-	return pop;
-}
-
-ldns_rr_list *
-ldns_rr_list_pop_rr_list(ldns_rr_list *rr_list, size_t howmany)
-{
-	/* pop a number of rr's and put them in a rr_list */
-	ldns_rr_list *popped;
-	ldns_rr *p;
-	size_t i = howmany;
-
-	popped = ldns_rr_list_new();
-
-	if (!popped) {
-		return NULL;
-	}
-
-
-	while(i > 0 &&
-			(p = ldns_rr_list_pop_rr(rr_list)) != NULL) {
-		ldns_rr_list_push_rr(popped, p);
-		i--;
-	}
-
-	if (i == howmany) { /* so i <= 0 */
-		ldns_rr_list_free(popped);
-		return NULL;
-	} else {
-		return popped;
-	}
-}
-
-
-bool
-ldns_rr_list_contains_rr(const ldns_rr_list *rr_list, ldns_rr *rr)
-{
-	size_t i;
-
-	if (!rr_list || !rr || ldns_rr_list_rr_count(rr_list) == 0) {
-		return false;
-	}
-
-	for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
-		if (rr == ldns_rr_list_rr(rr_list, i)) {
-			return true;
-		} else if (ldns_rr_compare(rr, ldns_rr_list_rr(rr_list, i)) == 0) {
-			return true;
-		}
-	}
-	return false;
-}
-
-bool
-ldns_is_rrset(ldns_rr_list *rr_list)
-{
-	ldns_rr_type t;
-	ldns_rr_class c;
-	ldns_rdf *o;
-	ldns_rr *tmp;
-	size_t i;
-
-	if (!rr_list || ldns_rr_list_rr_count(rr_list) == 0) {
-		return false;
-	}
-
-	tmp = ldns_rr_list_rr(rr_list, 0);
-
-	t = ldns_rr_get_type(tmp);
-	c = ldns_rr_get_class(tmp);
-	o = ldns_rr_owner(tmp);
-
-	/* compare these with the rest of the rr_list, start with 1 */
-	for (i = 1; i < ldns_rr_list_rr_count(rr_list); i++) {
-		tmp = ldns_rr_list_rr(rr_list, i);
-		if (t != ldns_rr_get_type(tmp)) {
-			return false;
-		}
-		if (c != ldns_rr_get_class(tmp)) {
-			return false;
-		}
-		if (ldns_rdf_compare(o, ldns_rr_owner(tmp)) != 0) {
-			return false;
-		}
-	}
-	return true;
-}
-
-bool
-ldns_rr_set_push_rr(ldns_rr_list *rr_list, ldns_rr *rr)
-{
-	size_t rr_count;
-	size_t i;
-	ldns_rr *last;
-
-	assert(rr != NULL);
-
-	rr_count = ldns_rr_list_rr_count(rr_list);
-
-	if (rr_count == 0) {
-		/* nothing there, so checking it is
-		 * not needed */
-		return ldns_rr_list_push_rr(rr_list, rr);
-	} else {
-		/* check with the final rr in the rr_list */
-		last = ldns_rr_list_rr(rr_list, rr_count - 1);
-
-		if (ldns_rr_get_class(last) != ldns_rr_get_class(rr)) {
-			return false;
-		}
-		if (ldns_rr_get_type(last) != ldns_rr_get_type(rr)) {
-			return false;
-		}
-		/* only check if not equal to RRSIG */
-		if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
-			if (ldns_rr_ttl(last) != ldns_rr_ttl(rr)) {
-				return false;
-			}
-		}
-		if (ldns_rdf_compare(ldns_rr_owner(last),
-					ldns_rr_owner(rr)) != 0) {
-			return false;
-		}
-		/* ok, still alive - check if the rr already
-		 * exists - if so, dont' add it */
-		for(i = 0; i < rr_count; i++) {
-			if(ldns_rr_compare(
-					ldns_rr_list_rr(rr_list, i), rr) == 0) {
-				return false;
-			}
-		}
-		/* it's safe, push it */
-		return ldns_rr_list_push_rr(rr_list, rr);
-	}
-}
-
-ldns_rr *
-ldns_rr_set_pop_rr(ldns_rr_list *rr_list)
-{
-	return ldns_rr_list_pop_rr(rr_list);
-}
-
-ldns_rr_list *
-ldns_rr_list_pop_rrset(ldns_rr_list *rr_list)
-{
-	ldns_rr_list *rrset;
-	ldns_rr *last_rr = NULL;
-	ldns_rr *next_rr;
-
-	if (!rr_list) {
-		return NULL;
-	}
-
-	rrset = ldns_rr_list_new();
-	if (!last_rr) {
-		last_rr = ldns_rr_list_pop_rr(rr_list);
-		if (!last_rr) {
-			ldns_rr_list_free(rrset);
-			return NULL;
-		} else {
-			ldns_rr_list_push_rr(rrset, last_rr);
-		}
-	}
-
-	if (ldns_rr_list_rr_count(rr_list) > 0) {
-		next_rr = ldns_rr_list_rr(rr_list, ldns_rr_list_rr_count(rr_list) - 1);
-	} else {
-		next_rr = NULL;
-	}
-
-	while (next_rr) {
-		if (
-			ldns_rdf_compare(ldns_rr_owner(next_rr),
-					 ldns_rr_owner(last_rr)) == 0
-			&&
-			ldns_rr_get_type(next_rr) == ldns_rr_get_type(last_rr)
-			&&
-			ldns_rr_get_class(next_rr) == ldns_rr_get_class(last_rr)
-		   ) {
-			ldns_rr_list_push_rr(rrset, ldns_rr_list_pop_rr(rr_list));
-			if (ldns_rr_list_rr_count(rr_list) > 0) {
-				last_rr = next_rr;
-				next_rr = ldns_rr_list_rr(rr_list, ldns_rr_list_rr_count(rr_list) - 1);
-			} else {
-				next_rr = NULL;
-			}
-		} else {
-			next_rr = NULL;
-		}
-	}
-
-	return rrset;
-}
-
-ldns_rr *
-ldns_rr_clone(const ldns_rr *rr)
-{
-	size_t i;
-	ldns_rr *new_rr;
-
-	if (!rr) {
-		return NULL;
-	}
-
-	new_rr = ldns_rr_new();
-	if (!new_rr) {
-		return NULL;
-	}
-	if (ldns_rr_owner(rr)) {
-		ldns_rr_set_owner(new_rr, ldns_rdf_clone(ldns_rr_owner(rr)));
-  	}
-	ldns_rr_set_ttl(new_rr, ldns_rr_ttl(rr));
-	ldns_rr_set_type(new_rr, ldns_rr_get_type(rr));
-	ldns_rr_set_class(new_rr, ldns_rr_get_class(rr));
-	ldns_rr_set_question(new_rr, ldns_rr_is_question(rr));
-
-	for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-        	if (ldns_rr_rdf(rr,i)) {
-        		ldns_rr_push_rdf(new_rr, ldns_rdf_clone(ldns_rr_rdf(rr, i)));
-                }
-	}
-
-	return new_rr;
-}
-
-ldns_rr_list *
-ldns_rr_list_clone(const ldns_rr_list *rrlist)
-{
-	size_t i;
-	ldns_rr_list *new_list;
-	ldns_rr *r;
-
-	if (!rrlist) {
-		return NULL;
-	}
-
-	new_list = ldns_rr_list_new();
-	if (!new_list) {
-		return NULL;
-	}
-	for (i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
-		r = ldns_rr_clone(
-			ldns_rr_list_rr(rrlist, i)
-		    );
-		if (!r) {
-			/* huh, failure in cloning */
-			ldns_rr_list_deep_free(new_list);
-			return NULL;
-		}
-		ldns_rr_list_push_rr(new_list, r);
-	}
-	return new_list;
-}
-
-
-static int
-qsort_schwartz_rr_compare(const void *a, const void *b)
-{
-	int result = 0;
-	ldns_rr *rr1, *rr2;
-	ldns_buffer *rr1_buf, *rr2_buf;
-	struct ldns_schwartzian_compare_struct *sa = *(struct ldns_schwartzian_compare_struct **) a;
-	struct ldns_schwartzian_compare_struct *sb = *(struct ldns_schwartzian_compare_struct **) b;
-	/* if we are doing 2wire, we need to do lowercasing on the dname (and maybe on the rdata)
-	 * this must be done for comparison only, so we need to have a temp var for both buffers,
-	 * which is only used when the transformed object value isn't there yet
-	 */
-	ldns_rr *canonical_a, *canonical_b;
-
-	rr1 = (ldns_rr *) sa->original_object;
-	rr2 = (ldns_rr *) sb->original_object;
-
-	result = ldns_rr_compare_no_rdata(rr1, rr2);
-
-	if (result == 0) {
-		if (!sa->transformed_object) {
-			canonical_a = ldns_rr_clone(sa->original_object);
-			ldns_rr2canonical(canonical_a);
-			sa->transformed_object = ldns_buffer_new(ldns_rr_uncompressed_size(canonical_a));
-			if (ldns_rr2buffer_wire(sa->transformed_object, canonical_a, LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
-		                ldns_buffer_free((ldns_buffer *)sa->transformed_object);
-                                sa->transformed_object = NULL;
-				ldns_rr_free(canonical_a);
-				return 0;
-			}
-			ldns_rr_free(canonical_a);
-		}
-		if (!sb->transformed_object) {
-			canonical_b = ldns_rr_clone(sb->original_object);
-			ldns_rr2canonical(canonical_b);
-			sb->transformed_object = ldns_buffer_new(ldns_rr_uncompressed_size(canonical_b));
-			if (ldns_rr2buffer_wire(sb->transformed_object, canonical_b, LDNS_SECTION_ANY) != LDNS_STATUS_OK) {
-		                ldns_buffer_free((ldns_buffer *)sa->transformed_object);
-		                ldns_buffer_free((ldns_buffer *)sb->transformed_object);
-                                sa->transformed_object = NULL;
-                                sb->transformed_object = NULL;
-				ldns_rr_free(canonical_b);
-				return 0;
-			}
-			ldns_rr_free(canonical_b);
-		}
-		rr1_buf = (ldns_buffer *) sa->transformed_object;
-		rr2_buf = (ldns_buffer *) sb->transformed_object;
-
-		result = ldns_rr_compare_wire(rr1_buf, rr2_buf);
-	}
-
-	return result;
-}
-
-void
-ldns_rr_list_sort(ldns_rr_list *unsorted)
-{
-	struct ldns_schwartzian_compare_struct **sortables;
-	size_t item_count;
-	size_t i;
-
-	if (unsorted) {
-		item_count = ldns_rr_list_rr_count(unsorted);
-
-		sortables = LDNS_XMALLOC(struct ldns_schwartzian_compare_struct *,
-					 item_count);
-                if(!sortables) return; /* no way to return error */
-		for (i = 0; i < item_count; i++) {
-			sortables[i] = LDNS_XMALLOC(struct ldns_schwartzian_compare_struct, 1);
-                        if(!sortables[i]) {
-                                /* free the allocated parts */
-                                while(i>0) {
-                                        i--;
-                                        LDNS_FREE(sortables[i]);
-                                }
-                                /* no way to return error */
-				LDNS_FREE(sortables);
-                                return;
-                        }
-			sortables[i]->original_object = ldns_rr_list_rr(unsorted, i);
-			sortables[i]->transformed_object = NULL;
-		}
-		qsort(sortables,
-		      item_count,
-		      sizeof(struct ldns_schwartzian_compare_struct *),
-		      qsort_schwartz_rr_compare);
-		for (i = 0; i < item_count; i++) {
-			unsorted->_rrs[i] = sortables[i]->original_object;
-			if (sortables[i]->transformed_object) {
-				ldns_buffer_free(sortables[i]->transformed_object);
-			}
-			LDNS_FREE(sortables[i]);
-		}
-		LDNS_FREE(sortables);
-	}
-}
-
-int
-ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2)
-{
-	size_t rr1_len;
-	size_t rr2_len;
-        size_t offset;
-
-	assert(rr1 != NULL);
-	assert(rr2 != NULL);
-
-	rr1_len = ldns_rr_uncompressed_size(rr1);
-	rr2_len = ldns_rr_uncompressed_size(rr2);
-
-	if (ldns_dname_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)) < 0) {
-		return -1;
-	} else if (ldns_dname_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)) > 0) {
-		return 1;
-	}
-
-        /* should return -1 if rr1 comes before rr2, so need to do rr1 - rr2, not rr2 - rr1 */
-        if (ldns_rr_get_class(rr1) != ldns_rr_get_class(rr2)) {
-            return ldns_rr_get_class(rr1) - ldns_rr_get_class(rr2);
-        }
-
-        /* should return -1 if rr1 comes before rr2, so need to do rr1 - rr2, not rr2 - rr1 */
-        if (ldns_rr_get_type(rr1) != ldns_rr_get_type(rr2)) {
-            return ldns_rr_get_type(rr1) - ldns_rr_get_type(rr2);
-        }
-
-        /* offset is the owername length + ttl + type + class + rdlen == start of wire format rdata */
-        offset = ldns_rdf_size(ldns_rr_owner(rr1)) + 4 + 2 + 2 + 2;
-        /* if either record doesn't have any RDATA... */
-        if (offset > rr1_len || offset > rr2_len) {
-            if (rr1_len == rr2_len) {
-              return 0;
-            }
-            return ((int) rr2_len - (int) rr1_len);
-        }
-
-	return 0;
-}
-
-int ldns_rr_compare_wire(ldns_buffer *rr1_buf, ldns_buffer *rr2_buf)
-{
-        size_t rr1_len, rr2_len, min_len, i, offset;
-
-        rr1_len = ldns_buffer_capacity(rr1_buf);
-        rr2_len = ldns_buffer_capacity(rr2_buf);
-
-        /* jump past dname (checked in earlier part)
-         * and especially past TTL */
-        offset = 0;
-        while (offset < rr1_len && *ldns_buffer_at(rr1_buf, offset) != 0) {
-          offset += *ldns_buffer_at(rr1_buf, offset) + 1;
-        }
-        /* jump to rdata section (PAST the rdata length field, otherwise
-           rrs with different lengths might be sorted erroneously */
-        offset += 11;
-	   min_len = (rr1_len < rr2_len) ? rr1_len : rr2_len;
-        /* Compare RRs RDATA byte for byte. */
-        for(i = offset; i < min_len; i++) {
-                if (*ldns_buffer_at(rr1_buf,i) < *ldns_buffer_at(rr2_buf,i)) {
-                        return -1;
-                } else if (*ldns_buffer_at(rr1_buf,i) > *ldns_buffer_at(rr2_buf,i)) {
-                        return +1;
-                }
-        }
-
-        /* If both RDATAs are the same up to min_len, then the shorter one sorts first. */
-        if (rr1_len < rr2_len) {
-                return -1;
-        } else if (rr1_len > rr2_len) {
-                return +1;
-	}
-        /* The RDATAs are equal. */
-        return 0;
-
-}
-
-int
-ldns_rr_compare(const ldns_rr *rr1, const ldns_rr *rr2)
-{
-	int result;
-	size_t rr1_len, rr2_len;
-
-	ldns_buffer *rr1_buf;
-	ldns_buffer *rr2_buf;
-
-	result = ldns_rr_compare_no_rdata(rr1, rr2);
-	if (result == 0) {
-		rr1_len = ldns_rr_uncompressed_size(rr1);
-		rr2_len = ldns_rr_uncompressed_size(rr2);
-
-		rr1_buf = ldns_buffer_new(rr1_len);
-		rr2_buf = ldns_buffer_new(rr2_len);
-
-		if (ldns_rr2buffer_wire_canonical(rr1_buf,
-								    rr1,
-								    LDNS_SECTION_ANY)
-		    != LDNS_STATUS_OK) {
-			ldns_buffer_free(rr1_buf);
-			ldns_buffer_free(rr2_buf);
-			return 0;
-		}
-		if (ldns_rr2buffer_wire_canonical(rr2_buf,
-								    rr2,
-								    LDNS_SECTION_ANY)
-		    != LDNS_STATUS_OK) {
-			ldns_buffer_free(rr1_buf);
-			ldns_buffer_free(rr2_buf);
-			return 0;
-		}
-
-		result = ldns_rr_compare_wire(rr1_buf, rr2_buf);
-
-		ldns_buffer_free(rr1_buf);
-		ldns_buffer_free(rr2_buf);
-	}
-
-	return result;
-}
-
-/* convert dnskey to a ds with the given algorithm,
- * then compare the result with the given ds */
-static int
-ldns_rr_compare_ds_dnskey(ldns_rr *ds,
-                          ldns_rr *dnskey)
-{
-	ldns_rr *ds_gen;
-	bool result = false;
-	ldns_hash algo;
-
-	if (!dnskey || !ds ||
-	    ldns_rr_get_type(ds) != LDNS_RR_TYPE_DS ||
-	    ldns_rr_get_type(dnskey) != LDNS_RR_TYPE_DNSKEY) {
-		return false;
-	}
-
-	if (ldns_rr_rdf(ds, 2) == NULL) {
-		return false;
-	}
-	algo = ldns_rdf2native_int8(ldns_rr_rdf(ds, 2));
-
-	ds_gen = ldns_key_rr2ds(dnskey, algo);
-	if (ds_gen) {
-		result = ldns_rr_compare(ds, ds_gen) == 0;
-		ldns_rr_free(ds_gen);
-	}
-	return result;
-}
-
-bool
-ldns_rr_compare_ds(const ldns_rr *orr1, const ldns_rr *orr2)
-{
-	bool result;
-	ldns_rr *rr1 = ldns_rr_clone(orr1);
-	ldns_rr *rr2 = ldns_rr_clone(orr2);
-
-	/* set ttls to zero */
-	ldns_rr_set_ttl(rr1, 0);
-	ldns_rr_set_ttl(rr2, 0);
-
-	if (ldns_rr_get_type(rr1) == LDNS_RR_TYPE_DS &&
-	    ldns_rr_get_type(rr2) == LDNS_RR_TYPE_DNSKEY) {
-		result = ldns_rr_compare_ds_dnskey(rr1, rr2);
-	} else if (ldns_rr_get_type(rr1) == LDNS_RR_TYPE_DNSKEY &&
-	    ldns_rr_get_type(rr2) == LDNS_RR_TYPE_DS) {
-		result = ldns_rr_compare_ds_dnskey(rr2, rr1);
-	} else {
-		result = (ldns_rr_compare(rr1, rr2) == 0);
-	}
-
-	ldns_rr_free(rr1);
-	ldns_rr_free(rr2);
-
-	return result;
-}
-
-int
-ldns_rr_list_compare(const ldns_rr_list *rrl1, const ldns_rr_list *rrl2)
-{
-	size_t i = 0;
-	int rr_cmp;
-
-	assert(rrl1 != NULL);
-	assert(rrl2 != NULL);
-
-	for (i = 0; i < ldns_rr_list_rr_count(rrl1) && i < ldns_rr_list_rr_count(rrl2); i++) {
-		rr_cmp = ldns_rr_compare(ldns_rr_list_rr(rrl1, i), ldns_rr_list_rr(rrl2, i));
-		if (rr_cmp != 0) {
-			return rr_cmp;
-		}
-	}
-
-	if (i == ldns_rr_list_rr_count(rrl1) &&
-	    i != ldns_rr_list_rr_count(rrl2)) {
-		return 1;
-	} else if (i == ldns_rr_list_rr_count(rrl2) &&
-	           i != ldns_rr_list_rr_count(rrl1)) {
-		return -1;
-	} else {
-		return 0;
-	}
-}
-
-size_t
-ldns_rr_uncompressed_size(const ldns_rr *r)
-{
-	size_t rrsize;
-	size_t i;
-
-	rrsize = 0;
-	/* add all the rdf sizes */
-	for(i = 0; i < ldns_rr_rd_count(r); i++) {
-		rrsize += ldns_rdf_size(ldns_rr_rdf(r, i));
-	}
-	/* ownername */
-	rrsize += ldns_rdf_size(ldns_rr_owner(r));
-	rrsize += LDNS_RR_OVERHEAD;
-	return rrsize;
-}
-
-void
-ldns_rr2canonical(ldns_rr *rr)
-{
-	uint16_t i;
-
-	if (!rr) {
-	  return;
-        }
-
-        ldns_dname2canonical(ldns_rr_owner(rr));
-
-	/*
-	 * lowercase the rdata dnames if the rr type is one
-	 * of the list in chapter 7 of RFC3597
-	 * Also added RRSIG, because a "Signer's Name" should be canonicalized
-	 * too. See dnssec-bis-updates-16. We can add it to this list because
-	 * the "Signer's Name"  is the only dname type rdata field in a RRSIG.
-	 */
-	switch(ldns_rr_get_type(rr)) {
-        	case LDNS_RR_TYPE_NS:
-        	case LDNS_RR_TYPE_MD:
-        	case LDNS_RR_TYPE_MF:
-        	case LDNS_RR_TYPE_CNAME:
-        	case LDNS_RR_TYPE_SOA:
-        	case LDNS_RR_TYPE_MB:
-        	case LDNS_RR_TYPE_MG:
-        	case LDNS_RR_TYPE_MR:
-        	case LDNS_RR_TYPE_PTR:
-        	case LDNS_RR_TYPE_MINFO:
-        	case LDNS_RR_TYPE_MX:
-        	case LDNS_RR_TYPE_RP:
-        	case LDNS_RR_TYPE_AFSDB:
-        	case LDNS_RR_TYPE_RT:
-        	case LDNS_RR_TYPE_SIG:
-        	case LDNS_RR_TYPE_PX:
-        	case LDNS_RR_TYPE_NXT:
-        	case LDNS_RR_TYPE_NAPTR:
-        	case LDNS_RR_TYPE_KX:
-        	case LDNS_RR_TYPE_SRV:
-        	case LDNS_RR_TYPE_DNAME:
-        	case LDNS_RR_TYPE_A6:
-        	case LDNS_RR_TYPE_RRSIG:
-			for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-				ldns_dname2canonical(ldns_rr_rdf(rr, i));
-			}
-			return;
-		default:
-			/* do nothing */
-			return;
-	}
-}
-
-void
-ldns_rr_list2canonical(ldns_rr_list *rr_list)
-{
-	size_t i;
-	for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
-		ldns_rr2canonical(ldns_rr_list_rr(rr_list, i));
-	}
-}
-
-uint8_t
-ldns_rr_label_count(ldns_rr *rr)
-{
-	if (!rr) {
-		return 0;
-	}
-	return ldns_dname_label_count(
-			ldns_rr_owner(rr));
-}
-
-/** \cond */
-static const ldns_rdf_type type_0_wireformat[] = { LDNS_RDF_TYPE_UNKNOWN };
-static const ldns_rdf_type type_a_wireformat[] = { LDNS_RDF_TYPE_A };
-static const ldns_rdf_type type_ns_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_md_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_mf_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_cname_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_soa_wireformat[] = {
-	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_INT32, 
-	LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_PERIOD,
-	LDNS_RDF_TYPE_PERIOD
-};
-static const ldns_rdf_type type_mb_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_mg_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_mr_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_wks_wireformat[] = {
-	LDNS_RDF_TYPE_A, LDNS_RDF_TYPE_WKS
-};
-static const ldns_rdf_type type_ptr_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_hinfo_wireformat[] = {
-	LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
-};
-static const ldns_rdf_type type_minfo_wireformat[] = {
-	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_mx_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_rp_wireformat[] = {
-	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_afsdb_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_x25_wireformat[] = { LDNS_RDF_TYPE_STR };
-static const ldns_rdf_type type_isdn_wireformat[] = {
-	LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
-};
-static const ldns_rdf_type type_rt_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_nsap_wireformat[] = {
-	LDNS_RDF_TYPE_NSAP
-};
-static const ldns_rdf_type type_nsap_ptr_wireformat[] = {
-	LDNS_RDF_TYPE_STR
-};
-static const ldns_rdf_type type_sig_wireformat[] = {
-	LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32,
-	LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_B64
-};
-static const ldns_rdf_type type_key_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_B64
-};
-static const ldns_rdf_type type_px_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_gpos_wireformat[] = {
-	LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR
-};
-static const ldns_rdf_type type_aaaa_wireformat[] = { LDNS_RDF_TYPE_AAAA };
-static const ldns_rdf_type type_loc_wireformat[] = { LDNS_RDF_TYPE_LOC };
-static const ldns_rdf_type type_nxt_wireformat[] = {
-	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_UNKNOWN
-};
-static const ldns_rdf_type type_eid_wireformat[] = {
-	LDNS_RDF_TYPE_HEX
-};
-static const ldns_rdf_type type_nimloc_wireformat[] = {
-	LDNS_RDF_TYPE_HEX
-};
-static const ldns_rdf_type type_srv_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_atma_wireformat[] = {
-	LDNS_RDF_TYPE_ATMA
-};
-static const ldns_rdf_type type_naptr_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_kx_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_cert_wireformat[] = {
-	 LDNS_RDF_TYPE_CERT_ALG, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_B64
-};
-static const ldns_rdf_type type_a6_wireformat[] = { LDNS_RDF_TYPE_UNKNOWN };
-static const ldns_rdf_type type_dname_wireformat[] = { LDNS_RDF_TYPE_DNAME };
-static const ldns_rdf_type type_sink_wireformat[] = { LDNS_RDF_TYPE_INT8,
-	LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_B64
-};
-static const ldns_rdf_type type_apl_wireformat[] = {
-	LDNS_RDF_TYPE_APL
-};
-static const ldns_rdf_type type_ds_wireformat[] = {
-	LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
-};
-static const ldns_rdf_type type_sshfp_wireformat[] = {
-	LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_HEX
-};
-static const ldns_rdf_type type_ipseckey_wireformat[] = {
-	LDNS_RDF_TYPE_IPSECKEY
-};
-static const ldns_rdf_type type_rrsig_wireformat[] = {
-	LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32,
-	LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_B64
-};
-static const ldns_rdf_type type_nsec_wireformat[] = {
-	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_NSEC
-};
-static const ldns_rdf_type type_dhcid_wireformat[] = {
-	LDNS_RDF_TYPE_B64
-};
-static const ldns_rdf_type type_talink_wireformat[] = {
-	LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
-};
-/*@unused@*/ static const ldns_rdf_type type_openpgpkey_wireformat[] = {
-	LDNS_RDF_TYPE_B64
-};
-/* nsec3 is some vars, followed by same type of data of nsec */
-static const ldns_rdf_type type_nsec3_wireformat[] = {
-/*	LDNS_RDF_TYPE_NSEC3_VARS, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC*/
-	LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_NSEC3_SALT, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, LDNS_RDF_TYPE_NSEC
-};
-
-static const ldns_rdf_type type_nsec3param_wireformat[] = {
-/*	LDNS_RDF_TYPE_NSEC3_PARAMS_VARS*/
-	LDNS_RDF_TYPE_INT8,
-	LDNS_RDF_TYPE_INT8,
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_NSEC3_SALT
-};
-
-static const ldns_rdf_type type_dnskey_wireformat[] = {
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_INT8,
-	LDNS_RDF_TYPE_ALG,
-	LDNS_RDF_TYPE_B64
-};
-static const ldns_rdf_type type_tkey_wireformat[] = {
-	LDNS_RDF_TYPE_DNAME,
-	LDNS_RDF_TYPE_TIME,
-	LDNS_RDF_TYPE_TIME,
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_INT16_DATA,
-	LDNS_RDF_TYPE_INT16_DATA,
-};
-static const ldns_rdf_type type_tsig_wireformat[] = {
-	LDNS_RDF_TYPE_DNAME,
-	LDNS_RDF_TYPE_TSIGTIME,
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_INT16_DATA,
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_INT16_DATA
-};
-static const ldns_rdf_type type_tlsa_wireformat[] = {
-	LDNS_RDF_TYPE_CERTIFICATE_USAGE,
-	LDNS_RDF_TYPE_SELECTOR,
-	LDNS_RDF_TYPE_MATCHING_TYPE,
-	LDNS_RDF_TYPE_HEX
-};
-static const ldns_rdf_type type_hip_wireformat[] = {
-	LDNS_RDF_TYPE_HIP
-};
-static const ldns_rdf_type type_nid_wireformat[] = {
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_ILNP64
-};
-static const ldns_rdf_type type_l32_wireformat[] = {
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_A
-};
-static const ldns_rdf_type type_l64_wireformat[] = {
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_ILNP64
-};
-static const ldns_rdf_type type_lp_wireformat[] = {
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_DNAME
-};
-static const ldns_rdf_type type_eui48_wireformat[] = {
-	LDNS_RDF_TYPE_EUI48
-};
-static const ldns_rdf_type type_eui64_wireformat[] = {
-	LDNS_RDF_TYPE_EUI64
-};
-#ifdef RRTYPE_URI
-static const ldns_rdf_type type_uri_wireformat[] = {
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_INT16,
-	LDNS_RDF_TYPE_LONG_STR
-};
-#endif
-static const ldns_rdf_type type_caa_wireformat[] = {
-	LDNS_RDF_TYPE_INT8,
-	LDNS_RDF_TYPE_TAG,
-	LDNS_RDF_TYPE_LONG_STR
-};
-/** \endcond */
-
-/** \cond */
-/* All RR's defined in 1035 are well known and can thus
- * be compressed. See RFC3597. These RR's are:
- * CNAME HINFO MB MD MF MG MINFO MR MX NULL NS PTR SOA TXT
- */
-static ldns_rr_descriptor rdata_field_descriptors[] = {
-	/* 0 */
-	{ 0, NULL, 0, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 1 */
-	{LDNS_RR_TYPE_A, "A", 1, 1, type_a_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 2 */
-	{LDNS_RR_TYPE_NS, "NS", 1, 1, type_ns_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 3 */
-	{LDNS_RR_TYPE_MD, "MD", 1, 1, type_md_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 4 */
-	{LDNS_RR_TYPE_MF, "MF", 1, 1, type_mf_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 5 */
-	{LDNS_RR_TYPE_CNAME, "CNAME", 1, 1, type_cname_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 6 */
-	{LDNS_RR_TYPE_SOA, "SOA", 7, 7, type_soa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 2 },
-	/* 7 */
-	{LDNS_RR_TYPE_MB, "MB", 1, 1, type_mb_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 8 */
-	{LDNS_RR_TYPE_MG, "MG", 1, 1, type_mg_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 9 */
-	{LDNS_RR_TYPE_MR, "MR", 1, 1, type_mr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 10 */
-	{LDNS_RR_TYPE_NULL, "NULL", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 11 */
-	{LDNS_RR_TYPE_WKS, "WKS", 2, 2, type_wks_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 12 */
-	{LDNS_RR_TYPE_PTR, "PTR", 1, 1, type_ptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 13 */
-	{LDNS_RR_TYPE_HINFO, "HINFO", 2, 2, type_hinfo_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 14 */
-	{LDNS_RR_TYPE_MINFO, "MINFO", 2, 2, type_minfo_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 2 },
-	/* 15 */
-	{LDNS_RR_TYPE_MX, "MX", 2, 2, type_mx_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_COMPRESS, 1 },
-	/* 16 */
-	{LDNS_RR_TYPE_TXT, "TXT", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
-	/* 17 */
-	{LDNS_RR_TYPE_RP, "RP", 2, 2, type_rp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
-	/* 18 */
-	{LDNS_RR_TYPE_AFSDB, "AFSDB", 2, 2, type_afsdb_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 19 */
-	{LDNS_RR_TYPE_X25, "X25", 1, 1, type_x25_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 20 */
-	{LDNS_RR_TYPE_ISDN, "ISDN", 1, 2, type_isdn_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 21 */
-	{LDNS_RR_TYPE_RT, "RT", 2, 2, type_rt_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 22 */
-	{LDNS_RR_TYPE_NSAP, "NSAP", 1, 1, type_nsap_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 23 */
-	{LDNS_RR_TYPE_NSAP_PTR, "NSAP-PTR", 1, 1, type_nsap_ptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 24 */
-	{LDNS_RR_TYPE_SIG, "SIG", 9, 9, type_sig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 25 */
-	{LDNS_RR_TYPE_KEY, "KEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 26 */
-	{LDNS_RR_TYPE_PX, "PX", 3, 3, type_px_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
-	/* 27 */
-	{LDNS_RR_TYPE_GPOS, "GPOS", 3, 3, type_gpos_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 28 */
-	{LDNS_RR_TYPE_AAAA, "AAAA", 1, 1, type_aaaa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 29 */
-	{LDNS_RR_TYPE_LOC, "LOC", 1, 1, type_loc_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 30 */
-	{LDNS_RR_TYPE_NXT, "NXT", 2, 2, type_nxt_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 31 */
-	{LDNS_RR_TYPE_EID, "EID", 1, 1, type_eid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 32 */
-	{LDNS_RR_TYPE_NIMLOC, "NIMLOC", 1, 1, type_nimloc_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 33 */
-	{LDNS_RR_TYPE_SRV, "SRV", 4, 4, type_srv_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 34 */
-	{LDNS_RR_TYPE_ATMA, "ATMA", 1, 1, type_atma_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 35 */
-	{LDNS_RR_TYPE_NAPTR, "NAPTR", 6, 6, type_naptr_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 36 */
-	{LDNS_RR_TYPE_KX, "KX", 2, 2, type_kx_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 37 */
-	{LDNS_RR_TYPE_CERT, "CERT", 4, 4, type_cert_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 38 */
-	{LDNS_RR_TYPE_A6, "A6", 1, 1, type_a6_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 39 */
-	{LDNS_RR_TYPE_DNAME, "DNAME", 1, 1, type_dname_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 40 */
-	{LDNS_RR_TYPE_SINK, "SINK", 1, 1, type_sink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 41 */
-	{LDNS_RR_TYPE_OPT, "OPT", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 42 */
-	{LDNS_RR_TYPE_APL, "APL", 0, 0, type_apl_wireformat, LDNS_RDF_TYPE_APL, LDNS_RR_NO_COMPRESS, 0 },
-	/* 43 */
-	{LDNS_RR_TYPE_DS, "DS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 44 */
-	{LDNS_RR_TYPE_SSHFP, "SSHFP", 3, 3, type_sshfp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 45 */
-	{LDNS_RR_TYPE_IPSECKEY, "IPSECKEY", 1, 1, type_ipseckey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 46 */
-	{LDNS_RR_TYPE_RRSIG, "RRSIG", 9, 9, type_rrsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 47 */
-	{LDNS_RR_TYPE_NSEC, "NSEC", 1, 2, type_nsec_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 48 */
-	{LDNS_RR_TYPE_DNSKEY, "DNSKEY", 4, 4, type_dnskey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 49 */
-	{LDNS_RR_TYPE_DHCID, "DHCID", 1, 1, type_dhcid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 50 */
-	{LDNS_RR_TYPE_NSEC3, "NSEC3", 5, 6, type_nsec3_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 51 */
-	{LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 52 */
-	{LDNS_RR_TYPE_TLSA, "TLSA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-{LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-	/* 55
-	 * Hip ends with 0 or more Rendezvous Servers represented as dname's.
-	 * Hence the LDNS_RDF_TYPE_DNAME _variable field and the _maximum field
-	 * set to 0.
-	 */
-	{LDNS_RR_TYPE_HIP, "HIP", 1, 1, type_hip_wireformat, LDNS_RDF_TYPE_DNAME, LDNS_RR_NO_COMPRESS, 0 },
-
-#ifdef RRTYPE_NINFO
-	/* 56 */
-	{LDNS_RR_TYPE_NINFO, "NINFO", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
-#else
-{LDNS_RR_TYPE_NULL, "TYPE56", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#endif
-#ifdef RRTYPE_RKEY
-	/* 57 */
-	{LDNS_RR_TYPE_RKEY, "RKEY", 4, 4, type_key_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#else
-{LDNS_RR_TYPE_NULL, "TYPE57", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#endif
-	/* 58 */
-	{LDNS_RR_TYPE_TALINK, "TALINK", 2, 2, type_talink_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 2 },
-
-	/* 59 */
-	{LDNS_RR_TYPE_CDS, "CDS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 60 */
-	{LDNS_RR_TYPE_CDNSKEY, "CDNSKEY", 4, 4, type_dnskey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-#ifdef RRTYPE_OPENPGPKEY
-	/* 61 */
-	{LDNS_RR_TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, type_openpgpkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#else
-{LDNS_RR_TYPE_NULL, "TYPE61", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#endif
-
-{LDNS_RR_TYPE_NULL, "TYPE62", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE66", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE67", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE68", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE69", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE70", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE71", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE72", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE73", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE74", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE75", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE76", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE77", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE78", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE79", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE80", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE81", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE82", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE83", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE84", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE85", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE86", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE87", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE88", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE89", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE90", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE91", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE92", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE93", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE94", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE95", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE96", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE97", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE98", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-	/* 99 */
-	{LDNS_RR_TYPE_SPF,  "SPF", 1, 0, NULL, LDNS_RDF_TYPE_STR, LDNS_RR_NO_COMPRESS, 0 },
-
-	/* UINFO  [IANA-Reserved] */
-{LDNS_RR_TYPE_NULL, "TYPE100", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* UID    [IANA-Reserved] */
-{LDNS_RR_TYPE_NULL, "TYPE101", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* GID    [IANA-Reserved] */
-{LDNS_RR_TYPE_NULL, "TYPE102", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* UNSPEC [IANA-Reserved] */
-{LDNS_RR_TYPE_NULL, "TYPE103", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-	/* 104 */
-	{LDNS_RR_TYPE_NID, "NID", 2, 2, type_nid_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 105 */
-	{LDNS_RR_TYPE_L32, "L32", 2, 2, type_l32_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 106 */
-	{LDNS_RR_TYPE_L64, "L64", 2, 2, type_l64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 107 */
-	{LDNS_RR_TYPE_LP, "LP", 2, 2, type_lp_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* 108 */
-	{LDNS_RR_TYPE_EUI48, "EUI48", 1, 1, type_eui48_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* 109 */
-	{LDNS_RR_TYPE_EUI64, "EUI64", 1, 1, type_eui64_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-{LDNS_RR_TYPE_NULL, "TYPE110", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE111", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE112", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE113", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE114", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE115", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE116", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE117", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE118", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE119", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE120", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE121", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE122", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE123", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE124", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE125", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE126", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE127", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE128", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE129", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE130", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE131", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE132", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE133", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE134", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE135", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE136", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE137", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE138", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE139", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE140", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE141", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE142", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE143", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE144", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE145", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE146", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE147", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE148", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE149", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE150", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE151", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE152", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE153", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE154", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE155", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE156", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE157", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE158", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE159", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE160", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE161", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE162", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE163", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE164", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE165", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE166", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE167", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE168", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE169", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE170", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE171", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE172", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE173", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE174", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE175", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE176", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE177", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE178", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE179", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE180", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE181", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE182", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE183", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE184", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE185", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE186", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE187", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE188", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE189", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE190", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE191", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE192", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE193", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE194", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE195", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE196", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE197", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE198", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE199", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE200", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE201", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE202", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE203", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE204", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE205", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE206", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE207", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE208", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE209", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE210", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE211", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE212", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE213", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE214", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE215", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE216", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE217", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE218", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE219", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE220", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE221", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE222", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE223", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE224", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE225", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE226", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE227", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE228", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE229", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE230", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE231", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE232", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE233", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE234", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE235", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE236", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE237", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE238", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE239", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE240", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE241", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE242", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE243", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE244", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE245", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE246", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE247", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE248", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-	/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
-	 * So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
-	 */
-	/* 249 */
-	{LDNS_RR_TYPE_TKEY, "TKEY", 7, 7, type_tkey_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-	/* LDNS_RDF_TYPE_INT16_DATA takes two fields (length and data) as one.
-	 * So, unlike RFC 2930 spec, we have 7 min/max rdf's i.s.o. 8/9.
-	 */
-	/* 250 */
-	{LDNS_RR_TYPE_TSIG, "TSIG", 7, 7, type_tsig_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 1 },
-
-	/* IXFR: A request for a transfer of an incremental zone transfer */
-{LDNS_RR_TYPE_NULL, "TYPE251", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* AXFR: A request for a transfer of an entire zone */
-{LDNS_RR_TYPE_NULL, "TYPE252", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* MAILB: A request for mailbox-related records (MB, MG or MR) */
-{LDNS_RR_TYPE_NULL, "TYPE253", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* MAILA: A request for mail agent RRs (Obsolete - see MX) */
-{LDNS_RR_TYPE_NULL, "TYPE254", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-	/* ANY: A request for all (available) records */
-{LDNS_RR_TYPE_NULL, "TYPE255", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-#ifdef RRTYPE_URI
-	/* 256 */
-	{LDNS_RR_TYPE_URI, "URI", 3, 3, type_uri_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#else
-{LDNS_RR_TYPE_NULL, "TYPE256", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#endif
-	/* 257 */
-	{LDNS_RR_TYPE_CAA, "CAA", 3, 3, type_caa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-
-/* split in array, no longer contiguous */
-
-#ifdef RRTYPE_TA
-	/* 32768 */
-	{LDNS_RR_TYPE_TA, "TA", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#else
-{LDNS_RR_TYPE_NULL, "TYPE32768", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-#endif
-	/* 32769 */
-	{LDNS_RR_TYPE_DLV, "DLV", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }
-};
-/** \endcond */
-
-/**
- * \def LDNS_RDATA_FIELD_DESCRIPTORS_COUNT
- * computes the number of rdata fields
- */
-#define LDNS_RDATA_FIELD_DESCRIPTORS_COUNT \
-	(sizeof(rdata_field_descriptors)/sizeof(rdata_field_descriptors[0]))
-
-
-/*---------------------------------------------------------------------------*
- * The functions below return an bitmap RDF with the space required to set
- * or unset all known RR types. Arguably these functions are better situated
- * in rdata.c, however for the space calculation it is necesarry to walk
- * through rdata_field_descriptors which is not easily possible from anywhere
- * other than rr.c where it is declared static.
- *
- * Alternatively rr.c could have provided an iterator for rr_type or 
- * rdf_descriptors, but this seemed overkill for internal use only.
- */
-static ldns_rr_descriptor* rdata_field_descriptors_end =
-	&rdata_field_descriptors[LDNS_RDATA_FIELD_DESCRIPTORS_COUNT];
-
-/* From RFC3845:
- *
- * 2.1.2.  The List of Type Bit Map(s) Field
- * 
- *    The RR type space is split into 256 window blocks, each representing
- *    the low-order 8 bits of the 16-bit RR type space.  Each block that
- *    has at least one active RR type is encoded using a single octet
- *    window number (from 0 to 255), a single octet bitmap length (from 1
- *    to 32) indicating the number of octets used for the window block's
- *    bitmap, and up to 32 octets (256 bits) of bitmap.
- * 
- *    Window blocks are present in the NSEC RR RDATA in increasing
- *    numerical order.
- * 
- *    "|" denotes concatenation
- * 
- *    Type Bit Map(s) Field = ( Window Block # | Bitmap Length | Bitmap ) +
- * 
- *    <cut>
- * 
- *    Blocks with no types present MUST NOT be included.  Trailing zero
- *    octets in the bitmap MUST be omitted.  The length of each block's
- *    bitmap is determined by the type code with the largest numerical
- *    value within that block, among the set of RR types present at the
- *    NSEC RR's owner name.  Trailing zero octets not specified MUST be
- *    interpreted as zero octets.
- */
-static ldns_status
-ldns_rdf_bitmap_known_rr_types_set(ldns_rdf** rdf, int value)
-{
-	uint8_t  window;		/*  most significant octet of type */
-	uint8_t  subtype;		/* least significant octet of type */
-	uint16_t windows[256]		/* Max subtype per window */
-#ifndef S_SPLINT_S
-	                      = { 0 }
-#endif
-	                             ;
-	ldns_rr_descriptor* d;	/* used to traverse rdata_field_descriptors */
-	size_t i;		/* used to traverse windows array */
-
-	size_t sz;			/* size needed for type bitmap rdf */
-	uint8_t* data = NULL;		/* rdf data */
-	uint8_t* dptr;			/* used to itraverse rdf data */
-
-	assert(rdf != NULL);
-
-	/* Which windows need to be in the bitmap rdf?
-	 */
-	for (d=rdata_field_descriptors; d < rdata_field_descriptors_end; d++) {
-		window  = d->_type >> 8;
-		subtype = d->_type & 0xff;
-		if (windows[window] < subtype) {
-			windows[window] = subtype;
-		}
-	}
-
-	/* How much space do we need in the rdf for those windows?
-	 */
-	sz = 0;
-	for (i = 0; i < 256; i++) {
-		if (windows[i]) {
-			sz += windows[i] / 8 + 3;
-		}
-	}
-	if (sz > 0) {
-		/* Format rdf data according RFC3845 Section 2.1.2 (see above)
-		 */
-		dptr = data = LDNS_XMALLOC(uint8_t, sz);
-		memset(data, value, sz);
-		if (!data) {
-			return LDNS_STATUS_MEM_ERR;
-		}
-		for (i = 0; i < 256; i++) {
-			if (windows[i]) {
-				*dptr++ = (uint8_t)i;
-				*dptr++ = (uint8_t)(windows[i] / 8 + 1);
-				dptr += dptr[-1];
-			}
-		}
-	}
-	/* Allocate and return rdf structure for the data
-	 */
-	*rdf = ldns_rdf_new(LDNS_RDF_TYPE_BITMAP, sz, data);
-	if (!*rdf) {
-		LDNS_FREE(data);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_rdf_bitmap_known_rr_types_space(ldns_rdf** rdf)
-{
-	return ldns_rdf_bitmap_known_rr_types_set(rdf, 0);
-}
-
-ldns_status
-ldns_rdf_bitmap_known_rr_types(ldns_rdf** rdf)
-{
-	return ldns_rdf_bitmap_known_rr_types_set(rdf, 255);
-}
-/* End of RDF bitmap functions
- *---------------------------------------------------------------------------*/
-
-
-const ldns_rr_descriptor *
-ldns_rr_descript(uint16_t type)
-{
-	size_t i;
-	if (type < LDNS_RDATA_FIELD_DESCRIPTORS_COMMON) {
-		return &rdata_field_descriptors[type];
-	} else {
-		/* because not all array index equals type code */
-		for (i = LDNS_RDATA_FIELD_DESCRIPTORS_COMMON;
-		     i < LDNS_RDATA_FIELD_DESCRIPTORS_COUNT;
-		     i++) {
-		        if (rdata_field_descriptors[i]._type == type) {
-		     		return &rdata_field_descriptors[i];
-			}
-		}
-                return &rdata_field_descriptors[0];
-	}
-}
-
-size_t
-ldns_rr_descriptor_minimum(const ldns_rr_descriptor *descriptor)
-{
-	if (descriptor) {
-		return descriptor->_minimum;
-	} else {
-		return 0;
-	}
-}
-
-size_t
-ldns_rr_descriptor_maximum(const ldns_rr_descriptor *descriptor)
-{
-	if (descriptor) {
-		if (descriptor->_variable != LDNS_RDF_TYPE_NONE) {
-			/* Should really be SIZE_MAX... bad FreeBSD.  */
-			return UINT_MAX;
-		} else {
-			return descriptor->_maximum;
-		}
-	} else {
-		return 0;
-	}
-}
-
-ldns_rdf_type
-ldns_rr_descriptor_field_type(const ldns_rr_descriptor *descriptor,
-                              size_t index)
-{
-	assert(descriptor != NULL);
-	assert(index < descriptor->_maximum
-	       || descriptor->_variable != LDNS_RDF_TYPE_NONE);
-	if (index < descriptor->_maximum) {
-		return descriptor->_wireformat[index];
-	} else {
-		return descriptor->_variable;
-	}
-}
-
-ldns_rr_type
-ldns_get_rr_type_by_name(const char *name)
-{
-	unsigned int i;
-	const char *desc_name;
-	const ldns_rr_descriptor *desc;
-
-	/* TYPEXX representation */
-	if (strlen(name) > 4 && strncasecmp(name, "TYPE", 4) == 0) {
-		return atoi(name + 4);
-	}
-
-	/* Normal types */
-	for (i = 0; i < (unsigned int) LDNS_RDATA_FIELD_DESCRIPTORS_COUNT; i++) {
-		desc = &rdata_field_descriptors[i];
-		desc_name = desc->_name;
-		if(desc_name &&
-		   strlen(name) == strlen(desc_name) &&
-		   strncasecmp(name, desc_name, strlen(desc_name)) == 0) {
-			/* because not all array index equals type code */
-			return desc->_type;
-		}
-	}
-
-	/* special cases for query types */
-	if (strlen(name) == 4 && strncasecmp(name, "IXFR", 4) == 0) {
-		return 251;
-	} else if (strlen(name) == 4 && strncasecmp(name, "AXFR", 4) == 0) {
-		return 252;
-	} else if (strlen(name) == 5 && strncasecmp(name, "MAILB", 5) == 0) {
-		return 253;
-	} else if (strlen(name) == 5 && strncasecmp(name, "MAILA", 5) == 0) {
-		return 254;
-	} else if (strlen(name) == 3 && strncasecmp(name, "ANY", 3) == 0) {
-		return 255;
-	}
-
-	return 0;
-}
-
-ldns_rr_class
-ldns_get_rr_class_by_name(const char *name)
-{
-	ldns_lookup_table *lt;
-
-	/* CLASSXX representation */
-	if (strlen(name) > 5 && strncasecmp(name, "CLASS", 5) == 0) {
-		return atoi(name + 5);
-	}
-
-	/* Normal types */
-	lt = ldns_lookup_by_name(ldns_rr_classes, name);
-
-	if (lt) {
-		return lt->id;
-	}
-	return 0;
-}
-
-
-ldns_rr_type
-ldns_rdf2rr_type(const ldns_rdf *rd)
-{
-        ldns_rr_type r;
-
-        if (!rd) {
-                return 0;
-        }
-
-        if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_TYPE) {
-                return 0;
-        }
-
-        r = (ldns_rr_type) ldns_rdf2native_int16(rd);
-        return r;
-}
-
-ldns_rr_type
-ldns_rr_list_type(const ldns_rr_list *rr_list)
-{
-	if (rr_list && ldns_rr_list_rr_count(rr_list) > 0) {
-		return ldns_rr_get_type(ldns_rr_list_rr(rr_list, 0));
-	} else {
-		return 0;
-	}
-}
-
-ldns_rdf *
-ldns_rr_list_owner(const ldns_rr_list *rr_list)
-{
-	if (rr_list && ldns_rr_list_rr_count(rr_list) > 0) {
-		return ldns_rr_owner(ldns_rr_list_rr(rr_list, 0));
-	} else {
-		return NULL;
-	}
-}
diff --git a/src/ldns/rr_functions.c b/src/ldns/rr_functions.c
deleted file mode 100644
index b03751b..0000000
--- a/src/ldns/rr_functions.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * rr_function.c
- *
- * function that operate on specific rr types
- *
- * (c) NLnet Labs, 2004-2006
- * See the file LICENSE for the license
- */
-
-/*
- * These come strait from perldoc Net::DNS::RR::xxx
- * first the read variant, then the write. This is
- * not complete.
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <limits.h>
-#include <strings.h>
-
-/**
- * return a specific rdf
- * \param[in] type type of RR
- * \param[in] rr   the rr itself
- * \param[in] pos  at which postion to get it
- * \return the rdf sought
- */
-static ldns_rdf *
-ldns_rr_function(ldns_rr_type type, const ldns_rr *rr, size_t pos)
-{
-        if (!rr || ldns_rr_get_type(rr) != type) {
-                return NULL;
-        }
-        return ldns_rr_rdf(rr, pos);
-}
-
-/**
- * set a specific rdf
- * \param[in] type type of RR
- * \param[in] rr   the rr itself
- * \param[in] rdf  the rdf to set
- * \param[in] pos  at which postion to set it
- * \return true or false
- */
-static bool
-ldns_rr_set_function(ldns_rr_type type, ldns_rr *rr, ldns_rdf *rdf, size_t pos)
-{
-        ldns_rdf *pop;
-        if (!rr || ldns_rr_get_type(rr) != type) {
-                return false;
-        }
-        pop = ldns_rr_set_rdf(rr, rdf, pos);
- 	ldns_rdf_deep_free(pop);
-        return true;
-}
-
-/* A/AAAA records */
-ldns_rdf *
-ldns_rr_a_address(const ldns_rr *r)
-{
-	/* 2 types to check, cannot use the macro */
-	if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A &&
-			ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) {
-		return NULL;
-	}
-	return ldns_rr_rdf(r, 0);
-}
-
-bool
-ldns_rr_a_set_address(ldns_rr *r, ldns_rdf *f)
-{
-	/* 2 types to check, cannot use the macro... */
-	ldns_rdf *pop;
-	if (!r || (ldns_rr_get_type(r) != LDNS_RR_TYPE_A &&
-			ldns_rr_get_type(r) != LDNS_RR_TYPE_AAAA)) {
-		return false;
-	}
-	pop = ldns_rr_set_rdf(r, f, 0);
-	if (pop) {
-		LDNS_FREE(pop);
-		return true;
-	} else {
-		return false;
-	}
-}
-
-/* NS record */
-ldns_rdf *
-ldns_rr_ns_nsdname(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_NS, r, 0);
-}
-
-/* MX record */
-ldns_rdf *
-ldns_rr_mx_preference(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_MX, r, 0);
-}
-
-ldns_rdf *
-ldns_rr_mx_exchange(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_MX, r, 1);
-}
-
-/* RRSIG record */
-ldns_rdf *
-ldns_rr_rrsig_typecovered(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 0);
-}
-
-bool
-ldns_rr_rrsig_set_typecovered(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 0);
-}
-
-ldns_rdf *
-ldns_rr_rrsig_algorithm(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 1);
-}
-
-bool
-ldns_rr_rrsig_set_algorithm(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 1);
-}
-
-ldns_rdf *
-ldns_rr_rrsig_labels(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 2);
-}
-
-bool
-ldns_rr_rrsig_set_labels(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 2);
-}
-
-ldns_rdf *
-ldns_rr_rrsig_origttl(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 3);
-}
-
-bool
-ldns_rr_rrsig_set_origttl(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 3);
-}
-
-ldns_rdf *
-ldns_rr_rrsig_expiration(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 4);
-}
-
-bool
-ldns_rr_rrsig_set_expiration(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 4);
-}
-
-ldns_rdf *
-ldns_rr_rrsig_inception(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 5);
-}
-
-bool
-ldns_rr_rrsig_set_inception(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 5);
-}
-
-ldns_rdf *
-ldns_rr_rrsig_keytag(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 6);
-}
-
-bool
-ldns_rr_rrsig_set_keytag(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 6);
-}
-
-ldns_rdf *
-ldns_rr_rrsig_signame(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 7);
-}
-
-bool
-ldns_rr_rrsig_set_signame(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 7);
-}
-
-ldns_rdf *
-ldns_rr_rrsig_sig(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_RRSIG, r, 8);
-}
-
-bool
-ldns_rr_rrsig_set_sig(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_RRSIG, r, f, 8);
-}
-
-/* DNSKEY record */
-ldns_rdf *
-ldns_rr_dnskey_flags(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 0);
-}
-
-bool
-ldns_rr_dnskey_set_flags(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 0);
-}
-
-ldns_rdf *
-ldns_rr_dnskey_protocol(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 1);
-}
-
-bool
-ldns_rr_dnskey_set_protocol(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 1);
-}
-
-ldns_rdf *
-ldns_rr_dnskey_algorithm(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 2);
-}
-
-bool
-ldns_rr_dnskey_set_algorithm(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 2);
-}
-
-ldns_rdf *
-ldns_rr_dnskey_key(const ldns_rr *r)
-{
-	return ldns_rr_function(LDNS_RR_TYPE_DNSKEY, r, 3);
-}
-
-bool
-ldns_rr_dnskey_set_key(ldns_rr *r, ldns_rdf *f)
-{
-	return ldns_rr_set_function(LDNS_RR_TYPE_DNSKEY, r, f, 3);
-}
-
-size_t
-ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
-                            const size_t len,
-                            const ldns_algorithm alg)
-{
-	/* for DSA keys */
-	uint8_t t;
-	
-	/* for RSA keys */
-	uint16_t exp;
-	uint16_t int16;
-	
-	switch ((ldns_signing_algorithm)alg) {
-	case LDNS_SIGN_DSA:
-	case LDNS_SIGN_DSA_NSEC3:
-		if (len > 0) {
-			t = keydata[0];
-			return (64 + t*8)*8;
-		} else {
-			return 0;
-		}
-		break;
-	case LDNS_SIGN_RSAMD5:
-	case LDNS_SIGN_RSASHA1:
-	case LDNS_SIGN_RSASHA1_NSEC3:
-#ifdef USE_SHA2
-	case LDNS_SIGN_RSASHA256:
-	case LDNS_SIGN_RSASHA512:
-#endif
-		if (len > 0) {
-			if (keydata[0] == 0) {
-				/* big exponent */
-				if (len > 3) {
-					memmove(&int16, keydata + 1, 2);
-					exp = ntohs(int16);
-					return (len - exp - 3)*8;
-				} else {
-					return 0;
-				}
-			} else {
-				exp = keydata[0];
-				return (len-exp-1)*8;
-			}
-		} else {
-			return 0;
-		}
-		break;
-#ifdef USE_GOST
-	case LDNS_SIGN_ECC_GOST:
-		return 512;
-#endif
-#ifdef USE_ECDSA
-        case LDNS_SIGN_ECDSAP256SHA256:
-                return 256;
-        case LDNS_SIGN_ECDSAP384SHA384:
-                return 384;
-#endif
-	case LDNS_SIGN_HMACMD5:
-		return len;
-	default:
-		return 0;
-	}
-}
-
-size_t 
-ldns_rr_dnskey_key_size(const ldns_rr *key) 
-{
-	if (!key || !ldns_rr_dnskey_key(key) 
-			|| !ldns_rr_dnskey_algorithm(key)) {
-		return 0;
-	}
-	return ldns_rr_dnskey_key_size_raw((unsigned char*)ldns_rdf_data(ldns_rr_dnskey_key(key)),
-	                                   ldns_rdf_size(ldns_rr_dnskey_key(key)),
-	                                   ldns_rdf2native_int8(ldns_rr_dnskey_algorithm(key))
-	                                  );
-}
-
-uint32_t ldns_soa_serial_identity(uint32_t ATTR_UNUSED(unused), void *data)
-{
-	return (uint32_t) (intptr_t) data;
-}
-
-uint32_t ldns_soa_serial_increment(uint32_t s, void *ATTR_UNUSED(unused))
-{
-	return ldns_soa_serial_increment_by(s, (void *)1);
-}
-
-uint32_t ldns_soa_serial_increment_by(uint32_t s, void *data)
-{
-	return s + (intptr_t) data;
-}
-
-uint32_t ldns_soa_serial_datecounter(uint32_t s, void *data)
-{
-	struct tm tm;
-	char s_str[11];
-	int32_t new_s;
-	time_t t = data ? (time_t) (intptr_t) data : ldns_time(NULL);
-
-	(void) strftime(s_str, 11, "%Y%m%d00", localtime_r(&t, &tm));
-	new_s = (int32_t) atoi(s_str);
-	return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s);
-}
-
-uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data)
-{
-	int32_t new_s = data ? (int32_t) (intptr_t) data 
-			     : (int32_t) ldns_time(NULL);
-	return new_s - ((int32_t) s) <= 0 ? s+1 : ((uint32_t) new_s);
-}
-
-void
-ldns_rr_soa_increment(ldns_rr *soa)
-{
-	ldns_rr_soa_increment_func_data(soa, ldns_soa_serial_increment, NULL);
-}
-
-void
-ldns_rr_soa_increment_func(ldns_rr *soa, ldns_soa_serial_increment_func_t f)
-{
-	ldns_rr_soa_increment_func_data(soa, f, NULL);
-}
-
-void
-ldns_rr_soa_increment_func_data(ldns_rr *soa, 
-		ldns_soa_serial_increment_func_t f, void *data)
-{
-	ldns_rdf *prev_soa_serial_rdf;
-	if ( !soa || !f || ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA 
-			|| !ldns_rr_rdf(soa, 2)) {
-		return;
-	}
-	prev_soa_serial_rdf = ldns_rr_set_rdf(
-		  soa
-		, ldns_native2rdf_int32(
-			  LDNS_RDF_TYPE_INT32
-			, (*f)( ldns_rdf2native_int32(
-					ldns_rr_rdf(soa, 2))
-			      , data
-			)
-		)
-		, 2
-	);
-	LDNS_FREE(prev_soa_serial_rdf);
-}
-
-void
-ldns_rr_soa_increment_func_int(ldns_rr *soa, 
-		ldns_soa_serial_increment_func_t f, int data)
-{
-	ldns_rr_soa_increment_func_data(soa, f, (void *) (intptr_t) data);
-}
-
diff --git a/src/ldns/sha1.c b/src/ldns/sha1.c
deleted file mode 100644
index 18a4dd2..0000000
--- a/src/ldns/sha1.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * modified for ldns by Jelte Jansen, original taken from OpenBSD:
- * 
- * SHA-1 in C
- * By Steve Reid <steve@edmweb.com>
- * 100% Public Domain
- * 
- * Test Vectors (from FIPS PUB 180-1)
- * "abc"
- *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
- * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
- * A million repetitions of "a"
- *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-*/
-
-/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
-
-#include <ldns/config.h>
-#include <ldns/ldns.h>
-#include <strings.h>
-
-#define SHA1HANDSOFF 1 /* Copies data before messing with it. */
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-/* blk0() and blk() perform the initial expand. */
-/* I got the idea of expanding during the round function from SSLeay */
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
-    |(rol(block->l[i],8)&0x00FF00FF))
-#else
-#define blk0(i) block->l[i]
-#endif
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
-    ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-/* Hash a single 512-bit block. This is the core of the algorithm. */
-
-void
-ldns_sha1_transform(uint32_t state[5], const unsigned char buffer[LDNS_SHA1_BLOCK_LENGTH])
-{
-    uint32_t a, b, c, d, e;
-    typedef union {
-        unsigned char c[64];
-        unsigned int l[16];
-    } CHAR64LONG16;
-    CHAR64LONG16* block;
-#ifdef SHA1HANDSOFF
-    unsigned char workspace[LDNS_SHA1_BLOCK_LENGTH];
-
-    block = (CHAR64LONG16 *)workspace;
-    memmove(block, buffer, LDNS_SHA1_BLOCK_LENGTH);
-#else
-    block = (CHAR64LONG16 *)buffer;
-#endif
-    /* Copy context->state[] to working vars */
-    a = state[0];
-    b = state[1];
-    c = state[2];
-    d = state[3];
-    e = state[4];
-
-    /* 4 rounds of 20 operations each. Loop unrolled. */
-    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
-    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
-    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
-    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
-    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
-    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
-    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
-    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
-    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
-    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
-    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
-    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
-    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
-    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
-    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
-    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-
-    /* Add the working vars back into context.state[] */
-    state[0] += a;
-    state[1] += b;
-    state[2] += c;
-    state[3] += d;
-    state[4] += e;
-    /* Wipe variables */
-    a = b = c = d = e = 0;
-}
-
-
-/* SHA1Init - Initialize new context */
-
-void
-ldns_sha1_init(ldns_sha1_ctx *context)
-{
-    /* SHA1 initialization constants */
-    context->count = 0;
-    context->state[0] = 0x67452301;
-    context->state[1] = 0xEFCDAB89;
-    context->state[2] = 0x98BADCFE;
-    context->state[3] = 0x10325476;
-    context->state[4] = 0xC3D2E1F0;
-}
-
-
-/* Run your data through this. */
-
-void
-ldns_sha1_update(ldns_sha1_ctx *context, const unsigned char *data, unsigned int len)
-{
-    unsigned int i;
-    unsigned int j;
-
-    j = (unsigned)(uint32_t)((context->count >> 3) & 63);
-    context->count += (len << 3);
-    if ((j + len) > 63) {
-        memmove(&context->buffer[j], data, (i = 64 - j));
-        ldns_sha1_transform(context->state, context->buffer);
-        for ( ; i + 63 < len; i += 64) {
-            ldns_sha1_transform(context->state, &data[i]);
-        }
-        j = 0;
-    }
-    else i = 0;
-    memmove(&context->buffer[j], &data[i], len - i);
-}
-
-
-/* Add padding and return the message digest. */
-
-void
-ldns_sha1_final(unsigned char digest[LDNS_SHA1_DIGEST_LENGTH], ldns_sha1_ctx *context)
-{
-    unsigned int i;
-    unsigned char finalcount[8];
-
-    for (i = 0; i < 8; i++) {
-        finalcount[i] = (unsigned char)((context->count >>
-            ((7 - (i & 7)) * 8)) & 255);  /* Endian independent */
-    }
-    ldns_sha1_update(context, (unsigned char *)"\200", 1);
-    while ((context->count & 504) != 448) {
-        ldns_sha1_update(context, (unsigned char *)"\0", 1);
-    }
-    ldns_sha1_update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
-
-    if (digest != NULL)
-        for (i = 0; i < LDNS_SHA1_DIGEST_LENGTH; i++) {
-            digest[i] = (unsigned char)((context->state[i >> 2] >>
-                ((3 - (i & 3)) * 8)) & 255);
-      }
-#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite its own static vars */
-    ldns_sha1_transform(context->state, context->buffer);
-#endif
-}
-
-unsigned char *
-ldns_sha1(unsigned char *data, unsigned int data_len, unsigned char *digest)
-{
-    ldns_sha1_ctx ctx;
-    ldns_sha1_init(&ctx);
-    ldns_sha1_update(&ctx, data, data_len);
-    ldns_sha1_final(digest, &ctx);
-    return digest;
-}
diff --git a/src/ldns/sha2.c b/src/ldns/sha2.c
deleted file mode 100644
index 9a27122..0000000
--- a/src/ldns/sha2.c
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
- * FILE:	sha2.c
- * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
- * 
- * Copyright (c) 2000-2001, Aaron D. Gifford
- * All rights reserved.
- *
- * Modified by Jelte Jansen to fit in ldns, and not clash with any
- * system-defined SHA code.
- * Changes:
- * - Renamed (external) functions and constants to fit ldns style
- * - Removed _End and _Data functions
- * - Added ldns_shaX(data, len, digest) convenience functions
- * - Removed prototypes of _Transform functions and made those static
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holder nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
- */
-
-#include <ldns/config.h>
-#include <string.h>	/* memcpy()/memset() or bcopy()/bzero() */
-#include <assert.h>	/* assert() */
-#include <ldns/sha2.h>
-
-/*
- * ASSERT NOTE:
- * Some sanity checking code is included using assert().  On my FreeBSD
- * system, this additional code can be removed by compiling with NDEBUG
- * defined.  Check your own systems manpage on assert() to see how to
- * compile WITHOUT the sanity checking code on your system.
- *
- * UNROLLED TRANSFORM LOOP NOTE:
- * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
- * loop version for the hash transform rounds (defined using macros
- * later in this file).  Either define on the command line, for example:
- *
- *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
- *
- * or define below:
- *
- *   #define SHA2_UNROLL_TRANSFORM
- *
- */
-
-
-/*** SHA-256/384/512 Machine Architecture Definitions *****************/
-/*
- * BYTE_ORDER NOTE:
- *
- * Please make sure that your system defines BYTE_ORDER.  If your
- * architecture is little-endian, make sure it also defines
- * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
- * equivilent.
- *
- * If your system does not define the above, then you can do so by
- * hand like this:
- *
- *   #define LITTLE_ENDIAN 1234
- *   #define BIG_ENDIAN    4321
- *
- * And for little-endian machines, add:
- *
- *   #define BYTE_ORDER LITTLE_ENDIAN 
- *
- * Or for big-endian machines:
- *
- *   #define BYTE_ORDER BIG_ENDIAN
- *
- * The FreeBSD machine this was written on defines BYTE_ORDER
- * appropriately by including <sys/types.h> (which in turn includes
- * <machine/endian.h> where the appropriate definitions are actually
- * made).
- */
-#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
-#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
-#endif
-
-typedef uint8_t  sha2_byte;	/* Exactly 1 byte */
-typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
-#ifdef S_SPLINT_S
-typedef unsigned long long sha2_word64; /* lint 8 bytes */
-#else
-typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
-#endif
-
-/*** SHA-256/384/512 Various Length Definitions ***********************/
-/* NOTE: Most of these are in sha2.h */
-#define ldns_sha256_SHORT_BLOCK_LENGTH	(LDNS_SHA256_BLOCK_LENGTH - 8)
-#define ldns_sha384_SHORT_BLOCK_LENGTH	(LDNS_SHA384_BLOCK_LENGTH - 16)
-#define ldns_sha512_SHORT_BLOCK_LENGTH	(LDNS_SHA512_BLOCK_LENGTH - 16)
-
-
-/*** ENDIAN REVERSAL MACROS *******************************************/
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define REVERSE32(w,x)	{ \
-	sha2_word32 tmp = (w); \
-	tmp = (tmp >> 16) | (tmp << 16); \
-	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
-}
-#ifndef S_SPLINT_S
-#define REVERSE64(w,x)	{ \
-	sha2_word64 tmp = (w); \
-	tmp = (tmp >> 32) | (tmp << 32); \
-	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
-	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
-	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
-	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
-}
-#else /* splint */
-#define REVERSE64(w,x) /* splint */
-#endif /* splint */
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-/*
- * Macro for incrementally adding the unsigned 64-bit integer n to the
- * unsigned 128-bit integer (represented using a two-element array of
- * 64-bit words):
- */
-#define ADDINC128(w,n)	{ \
-	(w)[0] += (sha2_word64)(n); \
-	if ((w)[0] < (n)) { \
-		(w)[1]++; \
-	} \
-}
-#ifdef S_SPLINT_S
-#undef ADDINC128
-#define ADDINC128(w,n) /* splint */
-#endif
-
-/*
- * Macros for copying blocks of memory and for zeroing out ranges
- * of memory.  Using these macros makes it easy to switch from
- * using memset()/memcpy() and using bzero()/bcopy().
- *
- * Please define either SHA2_USE_MEMSET_MEMCPY or define
- * SHA2_USE_BZERO_BCOPY depending on which function set you
- * choose to use:
- */
-#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
-/* Default to memset()/memcpy() if no option is specified */
-#define	SHA2_USE_MEMSET_MEMCPY	1
-#endif
-#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
-/* Abort with an error if BOTH options are defined */
-#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
-#endif
-
-#ifdef SHA2_USE_MEMSET_MEMCPY
-#define MEMSET_BZERO(p,l)	memset((p), 0, (l))
-#define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
-#endif
-#ifdef SHA2_USE_BZERO_BCOPY
-#define MEMSET_BZERO(p,l)	bzero((p), (l))
-#define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
-#endif
-
-
-/*** THE SIX LOGICAL FUNCTIONS ****************************************/
-/*
- * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
- *
- *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
- *   S is a ROTATION) because the SHA-256/384/512 description document
- *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
- *   same "backwards" definition.
- */
-/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
-#define R(b,x) 		((x) >> (b))
-/* 32-bit Rotate-right (used in SHA-256): */
-#define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
-/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
-#define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
-
-/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
-#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-/* Four of six logical functions used in SHA-256: */
-#define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
-#define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
-#define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
-#define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
-
-/* Four of six logical functions used in SHA-384 and SHA-512: */
-#define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
-#define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
-#define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
-#define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
-
-/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
-/* Hash constant words K for SHA-256: */
-static const sha2_word32 K256[64] = {
-	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
-	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
-	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
-	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
-	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
-	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
-	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
-	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
-	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
-	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
-	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
-	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
-	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
-	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
-	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
-	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
-};
-
-/* initial hash value H for SHA-256: */
-static const sha2_word32 ldns_sha256_initial_hash_value[8] = {
-	0x6a09e667UL,
-	0xbb67ae85UL,
-	0x3c6ef372UL,
-	0xa54ff53aUL,
-	0x510e527fUL,
-	0x9b05688cUL,
-	0x1f83d9abUL,
-	0x5be0cd19UL
-};
-
-/* Hash constant words K for SHA-384 and SHA-512: */
-static const sha2_word64 K512[80] = {
-	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
-	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
-	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
-	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
-	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
-	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
-	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
-	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
-	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
-	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
-	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
-	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
-	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
-	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
-	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
-	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
-	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
-	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
-	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
-	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
-	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
-	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
-	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
-	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
-	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
-	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
-	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
-	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
-	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
-	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
-	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
-	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
-	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
-	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
-	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
-	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
-	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
-	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
-	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
-	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
-};
-
-/* initial hash value H for SHA-384 */
-static const sha2_word64 sha384_initial_hash_value[8] = {
-	0xcbbb9d5dc1059ed8ULL,
-	0x629a292a367cd507ULL,
-	0x9159015a3070dd17ULL,
-	0x152fecd8f70e5939ULL,
-	0x67332667ffc00b31ULL,
-	0x8eb44a8768581511ULL,
-	0xdb0c2e0d64f98fa7ULL,
-	0x47b5481dbefa4fa4ULL
-};
-
-/* initial hash value H for SHA-512 */
-static const sha2_word64 sha512_initial_hash_value[8] = {
-	0x6a09e667f3bcc908ULL,
-	0xbb67ae8584caa73bULL,
-	0x3c6ef372fe94f82bULL,
-	0xa54ff53a5f1d36f1ULL,
-	0x510e527fade682d1ULL,
-	0x9b05688c2b3e6c1fULL,
-	0x1f83d9abfb41bd6bULL,
-	0x5be0cd19137e2179ULL
-};
-
-/*** SHA-256: *********************************************************/
-void ldns_sha256_init(ldns_sha256_CTX* context) {
-	if (context == (ldns_sha256_CTX*)0) {
-		return;
-	}
-	MEMCPY_BCOPY(context->state, ldns_sha256_initial_hash_value, LDNS_SHA256_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, LDNS_SHA256_BLOCK_LENGTH);
-	context->bitcount = 0;
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-256 round macros: */
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
-	REVERSE32(*data++, W256[j]); \
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
-             K256[j] + W256[j]; \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
-	     K256[j] + (W256[j] = *data++); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND256(a,b,c,d,e,f,g,h)	\
-	s0 = W256[(j+1)&0x0f]; \
-	s0 = sigma0_256(s0); \
-	s1 = W256[(j+14)&0x0f]; \
-	s1 = sigma1_256(s1); \
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
-	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-static void ldns_sha256_Transform(ldns_sha256_CTX* context,
-                                  const sha2_word32* data) {
-	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
-	sha2_word32	T1, *W256;
-	int		j;
-
-	W256 = (sha2_word32*)context->buffer;
-
-	/* initialize registers with the prev. intermediate value */
-	a = context->state[0];
-	b = context->state[1];
-	c = context->state[2];
-	d = context->state[3];
-	e = context->state[4];
-	f = context->state[5];
-	g = context->state[6];
-	h = context->state[7];
-
-	j = 0;
-	do {
-		/* Rounds 0 to 15 (unrolled): */
-		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
-		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
-		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
-		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
-		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
-		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
-		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
-		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
-	} while (j < 16);
-
-	/* Now for the remaining rounds to 64: */
-	do {
-		ROUND256(a,b,c,d,e,f,g,h);
-		ROUND256(h,a,b,c,d,e,f,g);
-		ROUND256(g,h,a,b,c,d,e,f);
-		ROUND256(f,g,h,a,b,c,d,e);
-		ROUND256(e,f,g,h,a,b,c,d);
-		ROUND256(d,e,f,g,h,a,b,c);
-		ROUND256(c,d,e,f,g,h,a,b);
-		ROUND256(b,c,d,e,f,g,h,a);
-	} while (j < 64);
-
-	/* Compute the current intermediate hash value */
-	context->state[0] += a;
-	context->state[1] += b;
-	context->state[2] += c;
-	context->state[3] += d;
-	context->state[4] += e;
-	context->state[5] += f;
-	context->state[6] += g;
-	context->state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-static void ldns_sha256_Transform(ldns_sha256_CTX* context,
-                                  const sha2_word32* data) {
-	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
-	sha2_word32	T1, T2, *W256;
-	int		j;
-
-	W256 = (sha2_word32*)context->buffer;
-
-	/* initialize registers with the prev. intermediate value */
-	a = context->state[0];
-	b = context->state[1];
-	c = context->state[2];
-	d = context->state[3];
-	e = context->state[4];
-	f = context->state[5];
-	g = context->state[6];
-	h = context->state[7];
-
-	j = 0;
-	do {
-#if BYTE_ORDER == LITTLE_ENDIAN
-		/* Copy data while converting to host byte order */
-		REVERSE32(*data++,W256[j]);
-		/* Apply the SHA-256 compression function to update a..h */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-		/* Apply the SHA-256 compression function to update a..h with copy */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		T2 = Sigma0_256(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 16);
-
-	do {
-		/* Part of the message block expansion: */
-		s0 = W256[(j+1)&0x0f];
-		s0 = sigma0_256(s0);
-		s1 = W256[(j+14)&0x0f];	
-		s1 = sigma1_256(s1);
-
-		/* Apply the SHA-256 compression function to update a..h */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 
-		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
-		T2 = Sigma0_256(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 64);
-
-	/* Compute the current intermediate hash value */
-	context->state[0] += a;
-	context->state[1] += b;
-	context->state[2] += c;
-	context->state[3] += d;
-	context->state[4] += e;
-	context->state[5] += f;
-	context->state[6] += g;
-	context->state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = T2 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-void ldns_sha256_update(ldns_sha256_CTX* context, const sha2_byte *data, size_t len) {
-	size_t freespace, usedspace;
-
-	if (len == 0) {
-		/* Calling with no data is valid - we do nothing */
-		return;
-	}
-
-	/* Sanity check: */
-	assert(context != (ldns_sha256_CTX*)0 && data != (sha2_byte*)0);
-
-	usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH;
-	if (usedspace > 0) {
-		/* Calculate how much free space is available in the buffer */
-		freespace = LDNS_SHA256_BLOCK_LENGTH - usedspace;
-
-		if (len >= freespace) {
-			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
-			context->bitcount += freespace << 3;
-			len -= freespace;
-			data += freespace;
-			ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
-		} else {
-			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
-			context->bitcount += len << 3;
-			/* Clean up: */
-			usedspace = freespace = 0;
-			return;
-		}
-	}
-	while (len >= LDNS_SHA256_BLOCK_LENGTH) {
-		/* Process as many complete blocks as we can */
-		ldns_sha256_Transform(context, (sha2_word32*)data);
-		context->bitcount += LDNS_SHA256_BLOCK_LENGTH << 3;
-		len -= LDNS_SHA256_BLOCK_LENGTH;
-		data += LDNS_SHA256_BLOCK_LENGTH;
-	}
-	if (len > 0) {
-		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->buffer, data, len);
-		context->bitcount += len << 3;
-	}
-	/* Clean up: */
-	usedspace = freespace = 0;
-}
-
-typedef union _ldns_sha2_buffer_union {
-        uint8_t*  theChars;
-        uint64_t* theLongs;
-} ldns_sha2_buffer_union;
-
-void ldns_sha256_final(sha2_byte digest[], ldns_sha256_CTX* context) {
-	sha2_word32	*d = (sha2_word32*)digest;
-	size_t usedspace;
-	ldns_sha2_buffer_union cast_var;
-
-	/* Sanity check: */
-	assert(context != (ldns_sha256_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha2_byte*)0) {
-		usedspace = (context->bitcount >> 3) % LDNS_SHA256_BLOCK_LENGTH;
-#if BYTE_ORDER == LITTLE_ENDIAN
-		/* Convert FROM host byte order */
-		REVERSE64(context->bitcount,context->bitcount);
-#endif
-		if (usedspace > 0) {
-			/* Begin padding with a 1 bit: */
-			context->buffer[usedspace++] = 0x80;
-
-			if (usedspace <= ldns_sha256_SHORT_BLOCK_LENGTH) {
-				/* Set-up for the last transform: */
-				MEMSET_BZERO(&context->buffer[usedspace], ldns_sha256_SHORT_BLOCK_LENGTH - usedspace);
-			} else {
-				if (usedspace < LDNS_SHA256_BLOCK_LENGTH) {
-					MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA256_BLOCK_LENGTH - usedspace);
-				}
-				/* Do second-to-last transform: */
-				ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
-
-				/* And set-up for the last transform: */
-				MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH);
-			}
-		} else {
-			/* Set-up for the last transform: */
-			MEMSET_BZERO(context->buffer, ldns_sha256_SHORT_BLOCK_LENGTH);
-
-			/* Begin padding with a 1 bit: */
-			*context->buffer = 0x80;
-		}
-		/* Set the bit count: */
-		cast_var.theChars = context->buffer;
-		cast_var.theLongs[ldns_sha256_SHORT_BLOCK_LENGTH / 8] = context->bitcount;
-
-		/* final transform: */
-		ldns_sha256_Transform(context, (sha2_word32*)context->buffer);
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < 8; j++) {
-				REVERSE32(context->state[j],context->state[j]);
-				*d++ = context->state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->state, LDNS_SHA256_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Clean up state data: */
-	MEMSET_BZERO(context, sizeof(ldns_sha256_CTX));
-	usedspace = 0;
-}
-
-unsigned char *
-ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest)
-{
-    ldns_sha256_CTX ctx;
-    ldns_sha256_init(&ctx);
-    ldns_sha256_update(&ctx, data, data_len);
-    ldns_sha256_final(digest, &ctx);
-    return digest;
-}
-
-/*** SHA-512: *********************************************************/
-void ldns_sha512_init(ldns_sha512_CTX* context) {
-	if (context == (ldns_sha512_CTX*)0) {
-		return;
-	}
-	MEMCPY_BCOPY(context->state, sha512_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH);
-	context->bitcount[0] = context->bitcount[1] =  0;
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-512 round macros: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
-	REVERSE64(*data++, W512[j]); \
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
-             K512[j] + W512[j]; \
-	(d) += T1, \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
-	j++
-
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
-             K512[j] + (W512[j] = *data++); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
-	j++
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND512(a,b,c,d,e,f,g,h)	\
-	s0 = W512[(j+1)&0x0f]; \
-	s0 = sigma0_512(s0); \
-	s1 = W512[(j+14)&0x0f]; \
-	s1 = sigma1_512(s1); \
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
-             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
-	j++
-
-static void ldns_sha512_Transform(ldns_sha512_CTX* context,
-                                  const sha2_word64* data) {
-	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
-	sha2_word64	T1, *W512 = (sha2_word64*)context->buffer;
-	int		j;
-
-	/* initialize registers with the prev. intermediate value */
-	a = context->state[0];
-	b = context->state[1];
-	c = context->state[2];
-	d = context->state[3];
-	e = context->state[4];
-	f = context->state[5];
-	g = context->state[6];
-	h = context->state[7];
-
-	j = 0;
-	do {
-		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
-		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
-		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
-		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
-		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
-		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
-		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
-		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
-	} while (j < 16);
-
-	/* Now for the remaining rounds up to 79: */
-	do {
-		ROUND512(a,b,c,d,e,f,g,h);
-		ROUND512(h,a,b,c,d,e,f,g);
-		ROUND512(g,h,a,b,c,d,e,f);
-		ROUND512(f,g,h,a,b,c,d,e);
-		ROUND512(e,f,g,h,a,b,c,d);
-		ROUND512(d,e,f,g,h,a,b,c);
-		ROUND512(c,d,e,f,g,h,a,b);
-		ROUND512(b,c,d,e,f,g,h,a);
-	} while (j < 80);
-
-	/* Compute the current intermediate hash value */
-	context->state[0] += a;
-	context->state[1] += b;
-	context->state[2] += c;
-	context->state[3] += d;
-	context->state[4] += e;
-	context->state[5] += f;
-	context->state[6] += g;
-	context->state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-static void ldns_sha512_Transform(ldns_sha512_CTX* context,
-                                  const sha2_word64* data) {
-	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
-	sha2_word64	T1, T2, *W512 = (sha2_word64*)context->buffer;
-	int		j;
-
-	/* initialize registers with the prev. intermediate value */
-	a = context->state[0];
-	b = context->state[1];
-	c = context->state[2];
-	d = context->state[3];
-	e = context->state[4];
-	f = context->state[5];
-	g = context->state[6];
-	h = context->state[7];
-
-	j = 0;
-	do {
-#if BYTE_ORDER == LITTLE_ENDIAN
-		/* Convert TO host byte order */
-		REVERSE64(*data++, W512[j]);
-		/* Apply the SHA-512 compression function to update a..h */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-		/* Apply the SHA-512 compression function to update a..h with copy */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		T2 = Sigma0_512(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 16);
-
-	do {
-		/* Part of the message block expansion: */
-		s0 = W512[(j+1)&0x0f];
-		s0 = sigma0_512(s0);
-		s1 = W512[(j+14)&0x0f];
-		s1 =  sigma1_512(s1);
-
-		/* Apply the SHA-512 compression function to update a..h */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
-		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
-		T2 = Sigma0_512(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 80);
-
-	/* Compute the current intermediate hash value */
-	context->state[0] += a;
-	context->state[1] += b;
-	context->state[2] += c;
-	context->state[3] += d;
-	context->state[4] += e;
-	context->state[5] += f;
-	context->state[6] += g;
-	context->state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = T2 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-void ldns_sha512_update(ldns_sha512_CTX* context, const sha2_byte *data, size_t len) {
-	size_t freespace, usedspace;
-
-	if (len == 0) {
-		/* Calling with no data is valid - we do nothing */
-		return;
-	}
-
-	/* Sanity check: */
-	assert(context != (ldns_sha512_CTX*)0 && data != (sha2_byte*)0);
-
-	usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH;
-	if (usedspace > 0) {
-		/* Calculate how much free space is available in the buffer */
-		freespace = LDNS_SHA512_BLOCK_LENGTH - usedspace;
-
-		if (len >= freespace) {
-			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
-			ADDINC128(context->bitcount, freespace << 3);
-			len -= freespace;
-			data += freespace;
-			ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
-		} else {
-			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
-			ADDINC128(context->bitcount, len << 3);
-			/* Clean up: */
-			usedspace = freespace = 0;
-			return;
-		}
-	}
-	while (len >= LDNS_SHA512_BLOCK_LENGTH) {
-		/* Process as many complete blocks as we can */
-		ldns_sha512_Transform(context, (sha2_word64*)data);
-		ADDINC128(context->bitcount, LDNS_SHA512_BLOCK_LENGTH << 3);
-		len -= LDNS_SHA512_BLOCK_LENGTH;
-		data += LDNS_SHA512_BLOCK_LENGTH;
-	}
-	if (len > 0) {
-		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->buffer, data, len);
-		ADDINC128(context->bitcount, len << 3);
-	}
-	/* Clean up: */
-	usedspace = freespace = 0;
-}
-
-static void ldns_sha512_Last(ldns_sha512_CTX* context) {
-	size_t usedspace;
-	ldns_sha2_buffer_union cast_var;
-
-	usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH;
-#if BYTE_ORDER == LITTLE_ENDIAN
-	/* Convert FROM host byte order */
-	REVERSE64(context->bitcount[0],context->bitcount[0]);
-	REVERSE64(context->bitcount[1],context->bitcount[1]);
-#endif
-	if (usedspace > 0) {
-		/* Begin padding with a 1 bit: */
-		context->buffer[usedspace++] = 0x80;
-
-		if (usedspace <= ldns_sha512_SHORT_BLOCK_LENGTH) {
-			/* Set-up for the last transform: */
-			MEMSET_BZERO(&context->buffer[usedspace], ldns_sha512_SHORT_BLOCK_LENGTH - usedspace);
-		} else {
-			if (usedspace < LDNS_SHA512_BLOCK_LENGTH) {
-				MEMSET_BZERO(&context->buffer[usedspace], LDNS_SHA512_BLOCK_LENGTH - usedspace);
-			}
-			/* Do second-to-last transform: */
-			ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
-
-			/* And set-up for the last transform: */
-			MEMSET_BZERO(context->buffer, LDNS_SHA512_BLOCK_LENGTH - 2);
-		}
-	} else {
-		/* Prepare for final transform: */
-		MEMSET_BZERO(context->buffer, ldns_sha512_SHORT_BLOCK_LENGTH);
-
-		/* Begin padding with a 1 bit: */
-		*context->buffer = 0x80;
-	}
-	/* Store the length of input data (in bits): */
-	cast_var.theChars = context->buffer;
-	cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8] = context->bitcount[1];
-	cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8 + 1] = context->bitcount[0];
-
-	/* final transform: */
-	ldns_sha512_Transform(context, (sha2_word64*)context->buffer);
-}
-
-void ldns_sha512_final(sha2_byte digest[], ldns_sha512_CTX* context) {
-	sha2_word64	*d = (sha2_word64*)digest;
-
-	/* Sanity check: */
-	assert(context != (ldns_sha512_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha2_byte*)0) {
-		ldns_sha512_Last(context);
-
-		/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < 8; j++) {
-				REVERSE64(context->state[j],context->state[j]);
-				*d++ = context->state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->state, LDNS_SHA512_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Zero out state data */
-	MEMSET_BZERO(context, sizeof(ldns_sha512_CTX));
-}
-
-unsigned char *
-ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest)
-{
-    ldns_sha512_CTX ctx;
-    ldns_sha512_init(&ctx);
-    ldns_sha512_update(&ctx, data, data_len);
-    ldns_sha512_final(digest, &ctx);
-    return digest;
-}
-
-/*** SHA-384: *********************************************************/
-void ldns_sha384_init(ldns_sha384_CTX* context) {
-	if (context == (ldns_sha384_CTX*)0) {
-		return;
-	}
-	MEMCPY_BCOPY(context->state, sha384_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, LDNS_SHA384_BLOCK_LENGTH);
-	context->bitcount[0] = context->bitcount[1] = 0;
-}
-
-void ldns_sha384_update(ldns_sha384_CTX* context, const sha2_byte* data, size_t len) {
-	ldns_sha512_update((ldns_sha512_CTX*)context, data, len);
-}
-
-void ldns_sha384_final(sha2_byte digest[], ldns_sha384_CTX* context) {
-	sha2_word64	*d = (sha2_word64*)digest;
-
-	/* Sanity check: */
-	assert(context != (ldns_sha384_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha2_byte*)0) {
-		ldns_sha512_Last((ldns_sha512_CTX*)context);
-
-		/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < 6; j++) {
-				REVERSE64(context->state[j],context->state[j]);
-				*d++ = context->state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->state, LDNS_SHA384_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Zero out state data */
-	MEMSET_BZERO(context, sizeof(ldns_sha384_CTX));
-}
-
-unsigned char *
-ldns_sha384(unsigned char *data, unsigned int data_len, unsigned char *digest)
-{
-    ldns_sha384_CTX ctx;
-    ldns_sha384_init(&ctx);
-    ldns_sha384_update(&ctx, data, data_len);
-    ldns_sha384_final(digest, &ctx);
-    return digest;
-}
diff --git a/src/ldns/str2host.c b/src/ldns/str2host.c
deleted file mode 100644
index cd07c89..0000000
--- a/src/ldns/str2host.c
+++ /dev/null
@@ -1,1604 +0,0 @@
-/*
- * str2host.c
- *
- * conversion routines from the presentation format
- * to the host format
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#include <time.h>
-
-#include <errno.h>
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#include <limits.h>
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-ldns_status
-ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
-{
-	char *end = NULL;
-	uint16_t *r;
-	r = LDNS_MALLOC(uint16_t);
-        if(!r) return LDNS_STATUS_MEM_ERR;
-
-	*r = htons((uint16_t)strtol((char *)shortstr, &end, 10));
-
-	if(*end != 0) {
-		LDNS_FREE(r);
-		return LDNS_STATUS_INVALID_INT;
-	} else {
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_INT16, sizeof(uint16_t), r);
-		LDNS_FREE(r);
-		return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-	}
-}
-
-ldns_status
-ldns_str2rdf_time(ldns_rdf **rd, const char *time)
-{
-	/* convert a time YYYYDDMMHHMMSS to wireformat */
-	uint16_t *r = NULL;
-	struct tm tm;
-	uint32_t l;
-	char *end;
-
-	/* Try to scan the time... */
-	r = (uint16_t*)LDNS_MALLOC(uint32_t);
-        if(!r) return LDNS_STATUS_MEM_ERR;
-
-	memset(&tm, 0, sizeof(tm));
-
-	if (strlen(time) == 14 &&
-	    sscanf(time, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6
-	   ) {
-	   	tm.tm_year -= 1900;
-	   	tm.tm_mon--;
-	   	/* Check values */
-		if (tm.tm_year < 70) {
-			goto bad_format;
-		}
-		if (tm.tm_mon < 0 || tm.tm_mon > 11) {
-			goto bad_format;
-		}
-		if (tm.tm_mday < 1 || tm.tm_mday > 31) {
-			goto bad_format;
-		}
-
-		if (tm.tm_hour < 0 || tm.tm_hour > 23) {
-			goto bad_format;
-		}
-
-		if (tm.tm_min < 0 || tm.tm_min > 59) {
-			goto bad_format;
-		}
-
-		if (tm.tm_sec < 0 || tm.tm_sec > 59) {
-			goto bad_format;
-		}
-
-		l = htonl(ldns_mktime_from_utc(&tm));
-		memcpy(r, &l, sizeof(uint32_t));
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_TIME, sizeof(uint32_t), r);
-		LDNS_FREE(r);
-		return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-	} else {
-		/* handle it as 32 bits timestamp */
-		l = htonl((uint32_t)strtol((char*)time, &end, 10));
-		if(*end != 0) {
-			LDNS_FREE(r);
-			return LDNS_STATUS_ERR;
-		} else {
-			memcpy(r, &l, sizeof(uint32_t));
-			*rd = ldns_rdf_new_frm_data(
-				LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
-			LDNS_FREE(r);
-		        return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-		}
-	}
-
-	bad_format:
-	LDNS_FREE(r);
-	return LDNS_STATUS_INVALID_TIME;
-}
-
-ldns_status
-ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
-{
-	uint8_t salt_length;
-	int c;
-	int salt_length_str;
-
-	uint8_t *salt;
-	uint8_t *data;
-	if(rd == NULL) {
-		return LDNS_STATUS_NULL;
-	}
-
-	salt_length_str = (int)strlen(salt_str);
-	if (salt_length_str == 1 && salt_str[0] == '-') {
-		salt_length_str = 0;
-	} else if (salt_length_str % 2 != 0) {
-		return LDNS_STATUS_INVALID_HEX;
-	}
-	if (salt_length_str > 512) {
-		return LDNS_STATUS_INVALID_HEX;
-	}
-
-	salt = LDNS_XMALLOC(uint8_t, salt_length_str / 2);
-        if(!salt) {
-                return LDNS_STATUS_MEM_ERR;
-        }
-	for (c = 0; c < salt_length_str; c += 2) {
-		if (isxdigit((int) salt_str[c]) && isxdigit((int) salt_str[c+1])) {
-			salt[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 +
-					  ldns_hexdigit_to_int(salt_str[c+1]);
-		} else {
-			LDNS_FREE(salt);
-			return LDNS_STATUS_INVALID_HEX;
-		}
-	}
-	salt_length = (uint8_t) (salt_length_str / 2);
-
-	data = LDNS_XMALLOC(uint8_t, 1 + salt_length);
-        if(!data) {
-	        LDNS_FREE(salt);
-                return LDNS_STATUS_MEM_ERR;
-        }
-	data[0] = salt_length;
-	memcpy(&data[1], salt, salt_length);
-	*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT, 1 + salt_length, data);
-	LDNS_FREE(data);
-	LDNS_FREE(salt);
-
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_period(ldns_rdf **rd,const char *period)
-{
-        uint32_t p;
-        const char *end;
-
-        /* Allocate required space... */
-        p = ldns_str2period(period, &end);
-
-        if (*end != 0) {
-		return LDNS_STATUS_ERR;
-        } else {
-                p = (uint32_t) htonl(p);
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_PERIOD, sizeof(uint32_t), &p);
-        }
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
-{
-	char *end;
-	uint16_t *r = NULL;
-	uint32_t l;
-
-	r = (uint16_t*)LDNS_MALLOC(uint32_t);
-        if(!r) return LDNS_STATUS_MEM_ERR;
-	errno = 0; /* must set to zero before call,
-			note race condition on errno */
-	if(*longstr == '-')
-		l = htonl((uint32_t)strtol((char*)longstr, &end, 10));
-	else	l = htonl((uint32_t)strtoul((char*)longstr, &end, 10));
-
-	if(*end != 0) {
-		LDNS_FREE(r);
-		return LDNS_STATUS_ERR;
-     } else {
-		if (errno == ERANGE) {
-			LDNS_FREE(r);
-			return LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW;
-		}
-		memcpy(r, &l, sizeof(uint32_t));
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
-		LDNS_FREE(r);
-	        return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-	}
-}
-
-ldns_status
-ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
-{
-	char *end;
-	uint8_t *r = NULL;
-
-	r = LDNS_MALLOC(uint8_t);
-        if(!r) return LDNS_STATUS_MEM_ERR;
-
-	*r = (uint8_t)strtol((char*)bytestr, &end, 10);
-
-        if(*end != 0) {
-		LDNS_FREE(r);
-		return LDNS_STATUS_ERR;
-        } else {
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_INT8, sizeof(uint8_t), r);
-		LDNS_FREE(r);
-	        return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-        }
-}
-
-
-/*
- * Checks whether the escaped value at **s is an decimal value or
- * a 'normally' escaped character (and not eos)
- *
- * The string pointer at *s is increased by either 0 (on error), 1 (on
- * normal escapes), or 3 (on decimals)
- *
- * Returns the number of bytes read from the escaped string, or
- * 0 on error
- */
-INLINE bool
-parse_escape(uint8_t *ch_p, const char** str_p)
-{
-	uint16_t val;
-
-	if ((*str_p)[0] && isdigit((*str_p)[0])  &&
-	    (*str_p)[1] && isdigit((*str_p)[1])  &&
-	    (*str_p)[2] && isdigit((*str_p)[2]))  {
-
-		val = (uint16_t)(((*str_p)[0] - '0') * 100 +
-				 ((*str_p)[1] - '0') *  10 +
-				 ((*str_p)[2] - '0'));
-
-		if (val > 255) {
-			goto error;
-		}
-		*ch_p = (uint8_t)val;
-		*str_p += 3;
-		return true;
-
-	} else if ((*str_p)[0] && !isdigit((*str_p)[0])) {
-
-		*ch_p = (uint8_t)*(*str_p)++;
-		return true;
-	}
-error:
-	*str_p = NULL;
-	return false; /* LDNS_STATUS_SYNTAX_BAD_ESCAPE */
-}
-
-INLINE bool
-parse_char(uint8_t *ch_p, const char** str_p)
-{
-	switch (**str_p) {
-
-	case '\0':	return false;
-
-	case '\\':	*str_p += 1;
-			return parse_escape(ch_p, str_p);
-
-	default:	*ch_p = (uint8_t)*(*str_p)++;
-			return true;
-	}
-}
-
-/*
- * No special care is taken, all dots are translated into
- * label seperators.
- * Could be made more efficient....we do 3 memcpy's in total...
- */
-ldns_status
-ldns_str2rdf_dname(ldns_rdf **d, const char *str)
-{
-	size_t len;
-
-	const char *s;
-	uint8_t *q, *pq, label_len;
-	uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
-	*d = NULL;
-
-	len = strlen((char*)str);
-	/* octet representation can make strings a lot longer than actual length */
-	if (len > LDNS_MAX_DOMAINLEN * 4) {
-		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
-	}
-	if (0 == len) {
-		return LDNS_STATUS_DOMAINNAME_UNDERFLOW;
-	}
-
-	/* root label */
-	if (1 == len && *str == '.') {
-		*d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, "\0");
-		return LDNS_STATUS_OK;
-	}
-
-	/* get on with the rest */
-
-	/* s is on the current character in the string
-         * pq points to where the labellength is going to go
-         * label_len keeps track of the current label's length
-	 * q builds the dname inside the buf array
-	 */
-	len = 0;
-	q = buf+1;
-	pq = buf;
-	label_len = 0;
-	for (s = str; *s; s++, q++) {
-		if (q > buf + LDNS_MAX_DOMAINLEN) {
-			return LDNS_STATUS_DOMAINNAME_OVERFLOW;
-		}
-		*q = 0;
-		switch (*s) {
-		case '.':
-			if (label_len > LDNS_MAX_LABELLEN) {
-				return LDNS_STATUS_LABEL_OVERFLOW;
-			}
-			if (label_len == 0) {
-				return LDNS_STATUS_EMPTY_LABEL;
-			}
-			len += label_len + 1;
-			*pq = label_len;
-			label_len = 0;
-			pq = q;
-			break;
-		case '\\':
-			/* octet value or literal char */
-			s += 1;
-			if (! parse_escape(q, &s)) {
-				return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
-			}
-			s -= 1;
-			label_len++;
-			break;
-		default:
-			*q = (uint8_t)*s;
-			label_len++;
-		}
-	}
-
-	/* add root label if last char was not '.' */
-	if (!ldns_dname_str_absolute(str)) {
-		if (q > buf + LDNS_MAX_DOMAINLEN) {
-			return LDNS_STATUS_DOMAINNAME_OVERFLOW;
-		}
-                if (label_len > LDNS_MAX_LABELLEN) {
-                        return LDNS_STATUS_LABEL_OVERFLOW;
-                }
-                if (label_len == 0) { /* label_len 0 but not . at end? */
-                        return LDNS_STATUS_EMPTY_LABEL;
-                }
-		len += label_len + 1;
-		*pq = label_len;
-		*q = 0;
-	}
-	len++;
-
-	*d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, len, buf);
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_str2rdf_a(ldns_rdf **rd, const char *str)
-{
-	in_addr_t address;
-        if (inet_pton(AF_INET, (char*)str, &address) != 1) {
-                return LDNS_STATUS_INVALID_IP4;
-        } else {
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_A, sizeof(address), &address);
-        }
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
-{
-	uint8_t address[LDNS_IP6ADDRLEN + 1];
-
-	if (inet_pton(AF_INET6, (char*)str, address) != 1) {
-		return LDNS_STATUS_INVALID_IP6;
-	} else {
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
-	}
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_str(ldns_rdf **rd, const char *str)
-{
-	uint8_t *data, *dp, ch = 0;
-	size_t length;
-
-	/* Worst case space requirement. We'll realloc to actual size later. */
-	dp = data = LDNS_XMALLOC(uint8_t, strlen(str) > 255 ? 256 : (strlen(str) + 1));
-	if (! data) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	/* Fill data (up to 255 characters) */
-	while (parse_char(&ch, &str)) {
-		if (dp - data >= 255) {
-			LDNS_FREE(data);
-			return LDNS_STATUS_INVALID_STR;
-		}
-		*++dp = ch;
-	}
-	if (! str) {
-		return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
-	}
-	length = (size_t)(dp - data);
-	/* Fix last length byte */
-	data[0] = (uint8_t)length;
-
-	/* Lose the overmeasure */
-	data = LDNS_XREALLOC(dp = data, uint8_t, length + 1);
-	if (! data) {
-		LDNS_FREE(dp);
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	/* Create rdf */
-	*rd = ldns_rdf_new(LDNS_RDF_TYPE_STR, length + 1, data);
-	if (! *rd) {
-		LDNS_FREE(data);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
-{
-	const char *my_str = str;
-
-	char *my_ip_str;
-	size_t ip_str_len;
-
-	uint16_t family;
-	bool negation;
-	uint8_t afdlength = 0;
-	uint8_t *afdpart;
-	uint8_t prefix;
-
-	uint8_t *data;
-
-	size_t i = 0;
-
-	/* [!]afi:address/prefix */
-	if (strlen(my_str) < 2
-			|| strchr(my_str, ':') == NULL
-			|| strchr(my_str, '/') == NULL
-			|| strchr(my_str, ':') > strchr(my_str, '/')) {
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	if (my_str[0] == '!') {
-		negation = true;
-		my_str += 1;
-	} else {
-		negation = false;
-	}
-
-	family = (uint16_t) atoi(my_str);
-
-	my_str = strchr(my_str, ':') + 1;
-
-	/* need ip addr and only ip addr for inet_pton */
-	ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
-	my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
-        if(!my_ip_str) return LDNS_STATUS_MEM_ERR;
-	strncpy(my_ip_str, my_str, ip_str_len + 1);
-	my_ip_str[ip_str_len] = '\0';
-
-	if (family == 1) {
-		/* ipv4 */
-		afdpart = LDNS_XMALLOC(uint8_t, 4);
-                if(!afdpart) {
-                        LDNS_FREE(my_ip_str);
-                        return LDNS_STATUS_MEM_ERR;
-                }
-		if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
-                        LDNS_FREE(my_ip_str);
-                        LDNS_FREE(afdpart);
-			return LDNS_STATUS_INVALID_STR;
-		}
-		for (i = 0; i < 4; i++) {
-			if (afdpart[i] != 0) {
-				afdlength = i + 1;
-			}
-		}
-	} else if (family == 2) {
-		/* ipv6 */
-		afdpart = LDNS_XMALLOC(uint8_t, 16);
-                if(!afdpart) {
-                        LDNS_FREE(my_ip_str);
-                        return LDNS_STATUS_MEM_ERR;
-                }
-		if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
-                        LDNS_FREE(my_ip_str);
-                        LDNS_FREE(afdpart);
-			return LDNS_STATUS_INVALID_STR;
-		}
-		for (i = 0; i < 16; i++) {
-			if (afdpart[i] != 0) {
-				afdlength = i + 1;
-			}
-		}
-	} else {
-		/* unknown family */
-		LDNS_FREE(my_ip_str);
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	my_str = strchr(my_str, '/') + 1;
-	prefix = (uint8_t) atoi(my_str);
-
-	data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
-        if(!data) {
-		LDNS_FREE(afdpart);
-		LDNS_FREE(my_ip_str);
-		return LDNS_STATUS_INVALID_STR;
-        }
-	ldns_write_uint16(data, family);
-	data[2] = prefix;
-	data[3] = afdlength;
-	if (negation) {
-		/* set bit 1 of byte 3 */
-		data[3] = data[3] | 0x80;
-	}
-
-	memcpy(data + 4, afdpart, afdlength);
-
-	*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
-	LDNS_FREE(afdpart);
-	LDNS_FREE(data);
-	LDNS_FREE(my_ip_str);
-
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
-{
-	uint8_t *buffer;
-	int16_t i;
-
-	buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
-        if(!buffer) {
-                return LDNS_STATUS_MEM_ERR;
-        }
-
-	i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
-						   ldns_b64_ntop_calculate_size(strlen(str)));
-	if (-1 == i) {
-		LDNS_FREE(buffer);
-		return LDNS_STATUS_INVALID_B64;
-	} else {
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
-	}
-	LDNS_FREE(buffer);
-
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
-{
-	uint8_t *buffer;
-	int i;
-	/* first byte contains length of actual b32 data */
-	uint8_t len = ldns_b32_pton_calculate_size(strlen(str));
-	buffer = LDNS_XMALLOC(uint8_t, len + 1);
-        if(!buffer) {
-                return LDNS_STATUS_MEM_ERR;
-        }
-	buffer[0] = len;
-
-	i = ldns_b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
-							 ldns_b32_ntop_calculate_size(strlen(str)));
-	if (i < 0) {
-                LDNS_FREE(buffer);
-		return LDNS_STATUS_INVALID_B32_EXT;
-	} else {
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
-	}
-	LDNS_FREE(buffer);
-
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
-{
-	uint8_t *t, *t_orig;
-	int i;
-	size_t len;
-
-	len = strlen(str);
-
-	if (len > LDNS_MAX_RDFLEN * 2) {
-		return LDNS_STATUS_LABEL_OVERFLOW;
-	} else {
-		t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
-                if(!t) {
-                        return LDNS_STATUS_MEM_ERR;
-                }
-		t_orig = t;
-		/* Now process octet by octet... */
-		while (*str) {
-			*t = 0;
-			if (isspace((int) *str)) {
-				str++;
-			} else {
-				for (i = 16; i >= 1; i -= 15) {
-					while (*str && isspace((int) *str)) { str++; }
-					if (*str) {
-						if (isxdigit((int) *str)) {
-							*t += ldns_hexdigit_to_int(*str) * i;
-						} else {
-                                                        LDNS_FREE(t_orig);
-							return LDNS_STATUS_ERR;
-						}
-						++str;
-					}
-				}
-				++t;
-			}
-		}
-		*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
-		                            (size_t) (t - t_orig),
-		                            t_orig);
-		LDNS_FREE(t_orig);
-	}
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
-{
-	const char *delimiters = "\n\t ";
-	char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
-	ldns_buffer *str_buf;
-	ssize_t c;
-	uint16_t cur_type;
-	size_t type_count = 0;
-	ldns_rr_type type_list[65536];
-	if(!token) return LDNS_STATUS_MEM_ERR;
-	if(rd == NULL) {
-		LDNS_FREE(token);
-		return LDNS_STATUS_NULL;
-	}
-
-	str_buf = LDNS_MALLOC(ldns_buffer);
-	if(!str_buf) {
-		LDNS_FREE(token);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
-	if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
-		LDNS_FREE(str_buf);
-		LDNS_FREE(token);
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
-                if(type_count >= sizeof(type_list)) {
-		        LDNS_FREE(str_buf);
-		        LDNS_FREE(token);
-                        return LDNS_STATUS_ERR;
-                }
-		cur_type = ldns_get_rr_type_by_name(token);
-		type_list[type_count] = cur_type;
-		type_count++;
-	}
-
-	*rd = ldns_dnssec_create_nsec_bitmap(type_list,
-	                                     type_count,
-	                                     LDNS_RR_TYPE_NSEC);
-
-	LDNS_FREE(token);
-	ldns_buffer_free(str_buf);
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_type(ldns_rdf **rd, const char *str)
-{
-	uint16_t type;
-	type = htons(ldns_get_rr_type_by_name(str));
-	/* ldns_rr_type is a 16 bit value */
-	*rd = ldns_rdf_new_frm_data(
-		LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_class(ldns_rdf **rd, const char *str)
-{
-	uint16_t klass;
-	klass = htons(ldns_get_rr_class_by_name(str));
-	/* class is 16 bit */
-	*rd = ldns_rdf_new_frm_data(
-		LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-/* An certificate alg field can either be specified as a 8 bits number
- * or by its symbolic name. Handle both
- */
-ldns_status
-ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
-{
-	ldns_lookup_table *lt;
-	ldns_status st;
-	uint8_t idd[2];
-	lt = ldns_lookup_by_name(ldns_cert_algorithms, str);
-	st = LDNS_STATUS_OK;
-
-	if (lt) {
-		ldns_write_uint16(idd, (uint16_t) lt->id);
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
-		if (!*rd) {
-			st = LDNS_STATUS_ERR;
-		}
-	} else {
-		/* try as-is (a number) */
-		st = ldns_str2rdf_int16(rd, str);
-		if (st == LDNS_STATUS_OK &&
-		    ldns_rdf2native_int16(*rd) == 0) {
-			st = LDNS_STATUS_CERT_BAD_ALGORITHM;
-		}
-	}
-
-	return st;
-}
-
-static ldns_lookup_table ldns_tlsa_certificate_usages[] = {
-	{ LDNS_TLSA_USAGE_PKIX_TA		, "PKIX-TA"  },
-	{ LDNS_TLSA_USAGE_PKIX_EE		, "PKIX-EE"  },
-	{ LDNS_TLSA_USAGE_DANE_TA		, "DANE-TA"  },
-	{ LDNS_TLSA_USAGE_DANE_EE		, "DANE-EE"  },
-	{ LDNS_TLSA_USAGE_PRIVCERT		, "PrivCert" }
-};
-
-static ldns_lookup_table ldns_tlsa_selectors[] = {
-	{ LDNS_TLSA_SELECTOR_CERT		, "Cert" },
-	{ LDNS_TLSA_SELECTOR_SPKI		, "SPKI" },
-	{ LDNS_TLSA_SELECTOR_PRIVSEL		, "PrivSel" }
-};
-
-static ldns_lookup_table ldns_tlsa_matching_types[] = {
-	{ LDNS_TLSA_MATCHING_TYPE_FULL		, "Full"      },
-	{ LDNS_TLSA_MATCHING_TYPE_SHA2_256	, "SHA2-256"  },
-	{ LDNS_TLSA_MATCHING_TYPE_SHA2_512	, "SHA2-512"  },
-	{ LDNS_TLSA_MATCHING_TYPE_PRIVMATCH	, "PrivMatch" }
-};
-
-static ldns_status
-ldns_str2rdf_mnemonic4int8(ldns_lookup_table *lt,
-		ldns_rdf **rd, const char *str)
-{
-	if ((lt = ldns_lookup_by_name(lt, str))) {
-		/* it was given as a integer */
-		*rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
-		if (!*rd)
-			return LDNS_STATUS_ERR;
-		else
-			return LDNS_STATUS_OK;
-	}
-	return ldns_str2rdf_int8(rd, str);
-}
-
-/* An alg field can either be specified as a 8 bits number
- * or by its symbolic name. Handle both
- */
-ldns_status
-ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
-{
-	return ldns_str2rdf_mnemonic4int8(ldns_algorithms, rd, str);
-}
-
-ldns_status
-ldns_str2rdf_certificate_usage(ldns_rdf **rd, const char *str)
-{
-	return ldns_str2rdf_mnemonic4int8(
-			ldns_tlsa_certificate_usages, rd, str);
-}
-
-ldns_status
-ldns_str2rdf_selector(ldns_rdf **rd, const char *str)
-{
-	return ldns_str2rdf_mnemonic4int8(ldns_tlsa_selectors, rd, str);
-}
-
-ldns_status
-ldns_str2rdf_matching_type(ldns_rdf **rd, const char *str)
-{
-	return ldns_str2rdf_mnemonic4int8(ldns_tlsa_matching_types, rd, str);
-}
-
-ldns_status
-ldns_str2rdf_unknown( ATTR_UNUSED(ldns_rdf **rd)
-		    , ATTR_UNUSED(const char *str)
-		    )
-{
-	/* this should be caught in an earlier time (general str2host for
-	   rr's */
-	return LDNS_STATUS_NOT_IMPL;
-}
-
-ldns_status
-ldns_str2rdf_service( ATTR_UNUSED(ldns_rdf **rd)
-		    , ATTR_UNUSED(const char *str)
-		    )
-{
-	/* is this used? is this actually WKS? or SRV? */
-	return LDNS_STATUS_NOT_IMPL;
-}
-
-static int
-loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
-{
-	/* read <digits>[.<digits>][mM] */
-	/* into mantissa exponent format for LOC type */
-	uint32_t meters = 0, cm = 0, val;
-	while (isblank(*my_str)) {
-		my_str++;
-	}
-	meters = (uint32_t)strtol(my_str, &my_str, 10);
-	if (*my_str == '.') {
-		my_str++;
-		cm = (uint32_t)strtol(my_str, &my_str, 10);
-	}
-	if (meters >= 1) {
-		*e = 2;
-		val = meters;
-	} else	{
-		*e = 0;
-		val = cm;
-	}
-	while(val >= 10) {
-		(*e)++;
-		val /= 10;
-	}
-	*m = (uint8_t)val;
-
-	if (*e > 9)
-		return 0;
-	if (*my_str == 'm' || *my_str == 'M') {
-		my_str++;
-	}
-	*endstr = my_str;
-	return 1;
-}
-
-ldns_status
-ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
-{
-	uint32_t latitude = 0;
-	uint32_t longitude = 0;
-	uint32_t altitude = 0;
-
-	uint8_t *data;
-	uint32_t equator = (uint32_t) ldns_power(2, 31);
-
-	uint32_t h = 0;
-	uint32_t m = 0;
-	uint8_t size_b = 1, size_e = 2;
-	uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
-	uint8_t vert_pre_b = 1, vert_pre_e = 3;
-
-	double s = 0.0;
-	bool northerness;
-	bool easterness;
-
-	char *my_str = (char *) str;
-
-	/* only support version 0 */
-	if (isdigit((int) *my_str)) {
-		h = (uint32_t) strtol(my_str, &my_str, 10);
-	} else {
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	while (isblank((int) *my_str)) {
-		my_str++;
-	}
-
-	if (isdigit((int) *my_str)) {
-		m = (uint32_t) strtol(my_str, &my_str, 10);
-	} else if (*my_str == 'N' || *my_str == 'S') {
-		goto north;
-	} else {
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	while (isblank((int) *my_str)) {
-		my_str++;
-	}
-
-	if (isdigit((int) *my_str)) {
-		s = strtod(my_str, &my_str);
-	}
-north:
-	while (isblank((int) *my_str)) {
-		my_str++;
-	}
-
-	if (*my_str == 'N') {
-		northerness = true;
-	} else if (*my_str == 'S') {
-		northerness = false;
-	} else {
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	my_str++;
-
-	/* store number */
-	s = 1000.0 * s;
-	/* add a little to make floor in conversion a round */
-	s += 0.0005;
-	latitude = (uint32_t) s;
-	latitude += 1000 * 60 * m;
-	latitude += 1000 * 60 * 60 * h;
-	if (northerness) {
-		latitude = equator + latitude;
-	} else {
-		latitude = equator - latitude;
-	}
-	while (isblank(*my_str)) {
-		my_str++;
-	}
-
-	if (isdigit((int) *my_str)) {
-		h = (uint32_t) strtol(my_str, &my_str, 10);
-	} else {
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	while (isblank((int) *my_str)) {
-		my_str++;
-	}
-
-	if (isdigit((int) *my_str)) {
-		m = (uint32_t) strtol(my_str, &my_str, 10);
-	} else if (*my_str == 'E' || *my_str == 'W') {
-		goto east;
-	} else {
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	while (isblank(*my_str)) {
-		my_str++;
-	}
-
-	if (isdigit((int) *my_str)) {
-		s = strtod(my_str, &my_str);
-	}
-
-east:
-	while (isblank(*my_str)) {
-		my_str++;
-	}
-
-	if (*my_str == 'E') {
-		easterness = true;
-	} else if (*my_str == 'W') {
-		easterness = false;
-	} else {
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	my_str++;
-
-	/* store number */
-	s *= 1000.0;
-	/* add a little to make floor in conversion a round */
-	s += 0.0005;
-	longitude = (uint32_t) s;
-	longitude += 1000 * 60 * m;
-	longitude += 1000 * 60 * 60 * h;
-
-	if (easterness) {
-		longitude += equator;
-	} else {
-		longitude = equator - longitude;
-	}
-
-	altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
-		10000000.0 + 0.5);
-	if (*my_str == 'm' || *my_str == 'M') {
-		my_str++;
-	}
-
-	if (strlen(my_str) > 0) {
-		if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
-			return LDNS_STATUS_INVALID_STR;
-	}
-
-	if (strlen(my_str) > 0) {
-		if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
-			return LDNS_STATUS_INVALID_STR;
-	}
-
-	if (strlen(my_str) > 0) {
-		if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
-			return LDNS_STATUS_INVALID_STR;
-	}
-
-	data = LDNS_XMALLOC(uint8_t, 16);
-        if(!data) {
-                return LDNS_STATUS_MEM_ERR;
-        }
-	data[0] = 0;
-	data[1] = 0;
-	data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
-	data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
-	data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
-	ldns_write_uint32(data + 4, latitude);
-	ldns_write_uint32(data + 8, longitude);
-	ldns_write_uint32(data + 12, altitude);
-
-	*rd = ldns_rdf_new_frm_data(
-		LDNS_RDF_TYPE_LOC, 16, data);
-
-	LDNS_FREE(data);
-	return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
-{
-	uint8_t *bitmap = NULL;
-	uint8_t *data;
-	int bm_len = 0;
-
-	struct protoent *proto = NULL;
-	struct servent *serv = NULL;
-	int serv_port;
-
-	ldns_buffer *str_buf;
-
-	char *proto_str = NULL;
-	char *token;
-	if(strlen(str) == 0)
-		token = LDNS_XMALLOC(char, 50);
-	else 	token = LDNS_XMALLOC(char, strlen(str)+2);
-	if(!token) return LDNS_STATUS_MEM_ERR;
-
-	str_buf = LDNS_MALLOC(ldns_buffer);
-	if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
-	ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
-	if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
-		LDNS_FREE(str_buf);
-		LDNS_FREE(token);
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
-		if (!proto_str) {
-			proto_str = strdup(token);
-			if (!proto_str) {
-				LDNS_FREE(bitmap);
-				LDNS_FREE(token);
-	                        ldns_buffer_free(str_buf);
-				return LDNS_STATUS_INVALID_STR;
-			}
-		} else {
-			serv = getservbyname(token, proto_str);
-			if (serv) {
-				serv_port = (int) ntohs((uint16_t) serv->s_port);
-			} else {
-				serv_port = atoi(token);
-			}
-			if (serv_port / 8 >= bm_len) {
-				uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
-                                if(!b2) {
-					LDNS_FREE(bitmap);
-				        LDNS_FREE(token);
-	                                ldns_buffer_free(str_buf);
-				        free(proto_str);
-				        return LDNS_STATUS_INVALID_STR;
-                                }
-				bitmap = b2;
-				/* set to zero to be sure */
-				for (; bm_len <= serv_port / 8; bm_len++) {
-					bitmap[bm_len] = 0;
-				}
-			}
-			ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
-		}
-	}
-
-	if (!proto_str || !bitmap) {
-		LDNS_FREE(bitmap);
-		LDNS_FREE(token);
-	        ldns_buffer_free(str_buf);
-	        free(proto_str);
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	data = LDNS_XMALLOC(uint8_t, bm_len + 1);
-        if(!data) {
-	        LDNS_FREE(token);
-	        ldns_buffer_free(str_buf);
-	        LDNS_FREE(bitmap);
-	        free(proto_str);
-	        return LDNS_STATUS_INVALID_STR;
-        }
-    if (proto_str)
-		proto = getprotobyname(proto_str);
-	if (proto) {
-		data[0] = (uint8_t) proto->p_proto;
-	} else if (proto_str) {
-		data[0] = (uint8_t) atoi(proto_str);
-	}
-	memcpy(data + 1, bitmap, (size_t) bm_len);
-
-	*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
-
-	LDNS_FREE(data);
-	LDNS_FREE(token);
-	ldns_buffer_free(str_buf);
-	LDNS_FREE(bitmap);
-	free(proto_str);
-#ifdef HAVE_ENDSERVENT
-	endservent();
-#endif
-#ifdef HAVE_ENDPROTOENT
-	endprotoent();
-#endif
-
-	if(!*rd) return LDNS_STATUS_MEM_ERR;
-
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
-{
-    size_t len, i;
-    char* nsap_str = (char*) str;
-
-	/* just a hex string with optional dots? */
-	if (str[0] != '0' || str[1] != 'x') {
-		return LDNS_STATUS_INVALID_STR;
-	} else {
-		len = strlen(str);
-		for (i=0; i < len; i++) {
-			if (nsap_str[i] == '.')
-				nsap_str[i] = ' ';
-        }
-		return ldns_str2rdf_hex(rd, str+2);
-	}
-}
-
-ldns_status
-ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
-{
-    size_t len, i;
-    char* atma_str = (char*) str;
-	ldns_status status;
-
-	/* just a hex string with optional dots? */
-	len = strlen(str);
-	for (i=0; i < len; i++) {
-		if (atma_str[i] == '.')
-			atma_str[i] = ' ';
-	}
-	status = ldns_str2rdf_hex(rd, str);
-    if (status != LDNS_STATUS_OK) {
-		; /* probably in e.164 format than */
-	}
-	return status;
-}
-
-ldns_status
-ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
-{
-	uint8_t precedence = 0;
-	uint8_t gateway_type = 0;
-	uint8_t algorithm = 0;
-	char* gateway = NULL;
-	char* publickey = NULL;
-	uint8_t *data;
-	ldns_buffer *str_buf;
-	char *token;
-	int token_count = 0;
-	int ipseckey_len = 0;
-	ldns_rdf* gateway_rdf = NULL;
-	ldns_rdf* publickey_rdf = NULL;
-	ldns_status status = LDNS_STATUS_OK;
-	
-	if(strlen(str) == 0)
-		token = LDNS_XMALLOC(char, 256);
-	else	token = LDNS_XMALLOC(char, strlen(str)+2);
-	if(!token) return LDNS_STATUS_MEM_ERR;
-
-	str_buf = LDNS_MALLOC(ldns_buffer);
-	if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
-	ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
-	if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
-		LDNS_FREE(str_buf);
-		LDNS_FREE(token);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
-		switch (token_count) {
-				case 0:
-					precedence = (uint8_t)atoi(token);
-					break;
-				case 1:
-					gateway_type = (uint8_t)atoi(token);
-					break;
-				case 2:
-					algorithm = (uint8_t)atoi(token);
-					break;
-				case 3:
-					gateway = strdup(token);
-					if (!gateway || (gateway_type == 0 &&
-							(token[0] != '.' || token[1] != '\0'))) {
-						LDNS_FREE(gateway);
-						LDNS_FREE(token);
-						ldns_buffer_free(str_buf);
-						return LDNS_STATUS_INVALID_STR;
-					}
-					break;
-				case 4:
-					publickey = strdup(token);
-					break;
-				default:
-					LDNS_FREE(token);
-					ldns_buffer_free(str_buf);
-					return LDNS_STATUS_INVALID_STR;
-					break;
-		}
-		token_count++;
-	}
-
-	if (!gateway || !publickey) {
-		if (gateway)
-			LDNS_FREE(gateway);
-		if (publickey)
-			LDNS_FREE(publickey);
-		LDNS_FREE(token);
-		ldns_buffer_free(str_buf);
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	if (gateway_type == 1) {
-		status = ldns_str2rdf_a(&gateway_rdf, gateway);
-	} else if (gateway_type == 2) {
-		status = ldns_str2rdf_aaaa(&gateway_rdf, gateway);
-	} else if (gateway_type == 3) {
-		status = ldns_str2rdf_dname(&gateway_rdf, gateway);
-	}
-
-	if (status != LDNS_STATUS_OK) {
-		if (gateway)
-			LDNS_FREE(gateway);
-		if (publickey)
-			LDNS_FREE(publickey);
-		LDNS_FREE(token);
-		ldns_buffer_free(str_buf);
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	status = ldns_str2rdf_b64(&publickey_rdf, publickey);
-
-	if (status != LDNS_STATUS_OK) {
-		if (gateway)
-			LDNS_FREE(gateway);
-		if (publickey)
-			LDNS_FREE(publickey);
-		LDNS_FREE(token);
-		ldns_buffer_free(str_buf);
-		if (gateway_rdf) ldns_rdf_free(gateway_rdf);
-		return LDNS_STATUS_INVALID_STR;
-	}
-
-	/* now copy all into one ipseckey rdf */
-	if (gateway_type)
-		ipseckey_len = 3 + (int)ldns_rdf_size(gateway_rdf) + (int)ldns_rdf_size(publickey_rdf);
-	else
-		ipseckey_len = 3 + (int)ldns_rdf_size(publickey_rdf);
-
-	data = LDNS_XMALLOC(uint8_t, ipseckey_len);
-	if(!data) {
-		if (gateway)
-			LDNS_FREE(gateway);
-		if (publickey)
-			LDNS_FREE(publickey);
-		LDNS_FREE(token);
-		ldns_buffer_free(str_buf);
-		if (gateway_rdf) ldns_rdf_free(gateway_rdf);
-		if (publickey_rdf) ldns_rdf_free(publickey_rdf);
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	data[0] = precedence;
-	data[1] = gateway_type;
-	data[2] = algorithm;
-
-	if (gateway_type) {
-		memcpy(data + 3,
-			ldns_rdf_data(gateway_rdf), ldns_rdf_size(gateway_rdf));
-		memcpy(data + 3 + ldns_rdf_size(gateway_rdf),
-			ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
-	} else {
-		memcpy(data + 3,
-			ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
-	}
-
-	*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY, (uint16_t) ipseckey_len, data);
-
-	if (gateway)
-		LDNS_FREE(gateway);
-	if (publickey)
-		LDNS_FREE(publickey);
-	LDNS_FREE(token);
-	ldns_buffer_free(str_buf);
-	ldns_rdf_free(gateway_rdf);
-	ldns_rdf_free(publickey_rdf);
-	LDNS_FREE(data);
-	if(!*rd) return LDNS_STATUS_MEM_ERR;
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_str2rdf_ilnp64(ldns_rdf **rd, const char *str)
-{
-	unsigned int a, b, c, d;
-	uint16_t shorts[4];
-	int l;
-
-	if (sscanf(str, "%4x:%4x:%4x:%4x%n", &a, &b, &c, &d, &l) != 4 ||
-			l != (int)strlen(str) || /* more data to read */
-			strpbrk(str, "+-")       /* signed hexes */
-			) {
-		return LDNS_STATUS_INVALID_ILNP64;
-	} else {
-		shorts[0] = htons(a);
-		shorts[1] = htons(b);
-		shorts[2] = htons(c);
-		shorts[3] = htons(d);
-		*rd = ldns_rdf_new_frm_data(
-			LDNS_RDF_TYPE_ILNP64, 4 * sizeof(uint16_t), &shorts);
-	}
-	return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_eui48(ldns_rdf **rd, const char *str)
-{
-	unsigned int a, b, c, d, e, f;
-	uint8_t bytes[6];
-	int l;
-
-	if (sscanf(str, "%2x-%2x-%2x-%2x-%2x-%2x%n",
-			&a, &b, &c, &d, &e, &f, &l) != 6 ||
-			l != (int)strlen(str)) {
-		return LDNS_STATUS_INVALID_EUI48;
-	} else {
-		bytes[0] = a;
-		bytes[1] = b;
-		bytes[2] = c;
-		bytes[3] = d;
-		bytes[4] = e;
-		bytes[5] = f;
-		*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_EUI48, 6, &bytes);
-	}
-	return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_eui64(ldns_rdf **rd, const char *str)
-{
-	unsigned int a, b, c, d, e, f, g, h;
-	uint8_t bytes[8];
-	int l;
-
-	if (sscanf(str, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n",
-			&a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 ||
-			l != (int)strlen(str)) {
-		return LDNS_STATUS_INVALID_EUI64;
-	} else {
-		bytes[0] = a;
-		bytes[1] = b;
-		bytes[2] = c;
-		bytes[3] = d;
-		bytes[4] = e;
-		bytes[5] = f;
-		bytes[6] = g;
-		bytes[7] = h;
-		*rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_EUI64, 8, &bytes);
-	}
-	return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
-}
-
-ldns_status
-ldns_str2rdf_tag(ldns_rdf **rd, const char *str)
-{
-	uint8_t *data;
-	const char* ptr;
-
-	if (strlen(str) > 255) {
-		return LDNS_STATUS_INVALID_TAG;
-	}
-	for (ptr = str; *ptr; ptr++) {
-		if (! isalnum(*ptr)) {
-			return LDNS_STATUS_INVALID_TAG;
-		}
-	}
-	data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
-        if (!data) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	data[0] = strlen(str);
-	memcpy(data + 1, str, strlen(str));
-
-	*rd = ldns_rdf_new(LDNS_RDF_TYPE_TAG, strlen(str) + 1, data);
-	if (!*rd) {
-		LDNS_FREE(data);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_str2rdf_long_str(ldns_rdf **rd, const char *str)
-{
-	uint8_t *data, *dp, ch = 0;
-	size_t length;
-
-	/* Worst case space requirement. We'll realloc to actual size later. */
-	dp = data = LDNS_XMALLOC(uint8_t, strlen(str));
-        if (! data) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	/* Fill data with parsed bytes */
-	while (parse_char(&ch, &str)) {
-		*dp++ = ch;
-		if (dp - data > LDNS_MAX_RDFLEN) {
-			LDNS_FREE(data);
-			return LDNS_STATUS_INVALID_STR;
-		}
-	}
-	if (! str) {
-		return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
-	}
-	length = (size_t)(dp - data);
-
-	/* Lose the overmeasure */
-	data = LDNS_XREALLOC(dp = data, uint8_t, length);
-	if (! data) {
-		LDNS_FREE(dp);
-		return LDNS_STATUS_MEM_ERR;
-	}
-
-	/* Create rdf */
-	*rd = ldns_rdf_new(LDNS_RDF_TYPE_LONG_STR, length, data);
-	if (! *rd) {
-		LDNS_FREE(data);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
-
-ldns_status
-ldns_str2rdf_hip(ldns_rdf **rd, const char *str)
-{
-	const char *hit = strchr(str, ' ') + 1;
-	const char *pk  = hit == NULL ? NULL : strchr(hit, ' ') + 1;
-	size_t hit_size = hit == NULL ? 0
-	                : pk  == NULL ? strlen(hit) : (size_t) (pk - hit) - 1;
-	size_t  pk_size = pk  == NULL ? 0 : strlen(pk);
-	size_t hit_wire_size = (hit_size + 1) / 2;
-	size_t  pk_wire_size = ldns_b64_pton_calculate_size(pk_size);
-	size_t rdf_size = 4 + hit_wire_size + pk_wire_size;
-
-	char *endptr; /* utility var for strtol usage */
-	int algorithm = strtol(str, &endptr, 10);
-
-	uint8_t *data, *dp;
-	int hi, lo, written;
-
-	if (hit_size == 0 || pk_size == 0 || (hit_size + 1) / 2 > 255
-			|| rdf_size > LDNS_MAX_RDFLEN
-			|| algorithm < 0 || algorithm > 255
-			|| (errno != 0 && algorithm == 0) /* out of range */
-			|| endptr == str                  /* no digits    */) {
-
-		return LDNS_STATUS_SYNTAX_ERR;
-	}
-	if ((data = LDNS_XMALLOC(uint8_t, rdf_size)) == NULL) {
-
-		return LDNS_STATUS_MEM_ERR;
-	}
-	/* From RFC 5205 section 5. HIP RR Storage Format:
-	 *************************************************
-
-	0                   1                   2                   3
-	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|  HIT length   | PK algorithm  |          PK length            |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|                                                               |
-	~                           HIT                                 ~
-	|                                                               |
-	+                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|                     |                                         |
-	+-+-+-+-+-+-+-+-+-+-+-+                                         +
-	|                           Public Key                          |
-	~                                                               ~
-	|                                                               |
-	+                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|                               |                               |
-	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
-	|                                                               |
-	~                       Rendezvous Servers                      ~
-	|                                                               |
-	+             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-	|             |
-	+-+-+-+-+-+-+-+                                                    */
-
-	data[0] = (uint8_t) hit_wire_size;
-	data[1] = (uint8_t) algorithm;
-
-	for (dp = data + 4; *hit && *hit != ' '; dp++) {
-
-		if ((hi = ldns_hexdigit_to_int(*hit++)) == -1 ||
-		    (lo = ldns_hexdigit_to_int(*hit++)) == -1) {
-
-			LDNS_FREE(data);
-			return LDNS_STATUS_INVALID_HEX;
-		}
-		*dp = (uint8_t) hi << 4 | lo;
-	}
-	if ((written = ldns_b64_pton(pk, dp, pk_wire_size)) <= 0) {
-
-		LDNS_FREE(data);
-		return LDNS_STATUS_INVALID_B64;
-	}
-
-	/* Because ldns_b64_pton_calculate_size isn't always correct:
-	 * (we have to fix it at some point)
-	 */
-	pk_wire_size = (uint16_t) written;
-	ldns_write_uint16(data + 2, pk_wire_size);
-	rdf_size = 4 + hit_wire_size + pk_wire_size;
-
-	/* Create rdf */
-	if (! (*rd = ldns_rdf_new(LDNS_RDF_TYPE_HIP, rdf_size, data))) {
-
-		LDNS_FREE(data);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
diff --git a/src/ldns/tsig.c b/src/ldns/tsig.c
deleted file mode 100644
index 53aa85e..0000000
--- a/src/ldns/tsig.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * tsig.c
- *
- * contains the functions needed for TSIG [RFC2845]
- *
- * (c) 2005-2006 NLnet Labs
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <strings.h>
-
-#ifdef HAVE_SSL
-#include <openssl/hmac.h>
-#include <openssl/md5.h>
-#endif /* HAVE_SSL */
-
-char *
-ldns_tsig_algorithm(ldns_tsig_credentials *tc)
-{
-	return tc->algorithm;
-}
-
-char *
-ldns_tsig_keyname(ldns_tsig_credentials *tc)
-{
-	return tc->keyname;
-}
-
-char *
-ldns_tsig_keydata(ldns_tsig_credentials *tc)
-{
-	return tc->keydata;
-}
-
-char *
-ldns_tsig_keyname_clone(ldns_tsig_credentials *tc)
-{
-	return strdup(tc->keyname);
-}
-
-char *
-ldns_tsig_keydata_clone(ldns_tsig_credentials *tc)
-{
-	return strdup(tc->keydata);
-}
-
-/*
- *  Makes an exact copy of the wire, but with the tsig rr removed
- */
-static uint8_t *
-ldns_tsig_prepare_pkt_wire(uint8_t *wire, size_t wire_len, size_t *result_len)
-{
-	uint8_t *wire2 = NULL;
-	uint16_t qd_count;
-	uint16_t an_count;
-	uint16_t ns_count;
-	uint16_t ar_count;
-	ldns_rr *rr;
-
-	size_t pos;
-	uint16_t i;
-
-	ldns_status status;
-
-	if(wire_len < LDNS_HEADER_SIZE) {
-		return NULL;
-	}
-	/* fake parse the wire */
-	qd_count = LDNS_QDCOUNT(wire);
-	an_count = LDNS_ANCOUNT(wire);
-	ns_count = LDNS_NSCOUNT(wire);
-	ar_count = LDNS_ARCOUNT(wire);
-
-	if (ar_count > 0) {
-		ar_count--;
-	} else {
-		return NULL;
-	}
-
-	pos = LDNS_HEADER_SIZE;
-
-	for (i = 0; i < qd_count; i++) {
-		status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_QUESTION);
-		if (status != LDNS_STATUS_OK) {
-			return NULL;
-		}
-		ldns_rr_free(rr);
-	}
-
-	for (i = 0; i < an_count; i++) {
-		status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_ANSWER);
-		if (status != LDNS_STATUS_OK) {
-			return NULL;
-		}
-		ldns_rr_free(rr);
-	}
-
-	for (i = 0; i < ns_count; i++) {
-		status = ldns_wire2rr(&rr, wire, wire_len, &pos, LDNS_SECTION_AUTHORITY);
-		if (status != LDNS_STATUS_OK) {
-			return NULL;
-		}
-		ldns_rr_free(rr);
-	}
-
-	for (i = 0; i < ar_count; i++) {
-		status = ldns_wire2rr(&rr, wire, wire_len, &pos,
-				LDNS_SECTION_ADDITIONAL);
-		if (status != LDNS_STATUS_OK) {
-			return NULL;
-		}
-		ldns_rr_free(rr);
-	}
-
-	*result_len = pos;
-	wire2 = LDNS_XMALLOC(uint8_t, *result_len);
-	if(!wire2) {
-		return NULL;
-	}
-	memcpy(wire2, wire, *result_len);
-
-	ldns_write_uint16(wire2 + LDNS_ARCOUNT_OFF, ar_count);
-
-	return wire2;
-}
-
-#ifdef HAVE_SSL
-static const EVP_MD *
-ldns_digest_function(char *name)
-{
-	/* these are the mandatory algorithms from RFC4635 */
-	/* The optional algorithms are not yet implemented */
-	if (strcasecmp(name, "hmac-sha256.") == 0) {
-#ifdef HAVE_EVP_SHA256
-		return EVP_sha256();
-#else
-		return NULL;
-#endif
-	} else if (strcasecmp(name, "hmac-sha1.") == 0) {
-		return EVP_sha1();
-	} else if (strcasecmp(name, "hmac-md5.sig-alg.reg.int.") == 0) {
-		return EVP_md5();
-	} else {
-		return NULL;
-	}
-}
-#endif
-
-#ifdef HAVE_SSL
-static ldns_status
-ldns_tsig_mac_new(ldns_rdf **tsig_mac, uint8_t *pkt_wire, size_t pkt_wire_size,
-		const char *key_data, ldns_rdf *key_name_rdf, ldns_rdf *fudge_rdf,
-		ldns_rdf *algorithm_rdf, ldns_rdf *time_signed_rdf, ldns_rdf *error_rdf,
-		ldns_rdf *other_data_rdf, ldns_rdf *orig_mac_rdf, int tsig_timers_only)
-{
-	ldns_status status;
-	char *wireformat;
-	int wiresize;
-	unsigned char *mac_bytes = NULL;
-	unsigned char *key_bytes = NULL;
-	int key_size;
-	const EVP_MD *digester;
-	char *algorithm_name = NULL;
-	unsigned int md_len = EVP_MAX_MD_SIZE;
-	ldns_rdf *result = NULL;
-	ldns_buffer *data_buffer = NULL;
-	ldns_rdf *canonical_key_name_rdf = NULL;
-	ldns_rdf *canonical_algorithm_rdf = NULL;
-	
-	if (key_name_rdf == NULL || algorithm_rdf == NULL) {
-		return LDNS_STATUS_NULL;
-	}
-	canonical_key_name_rdf  = ldns_rdf_clone(key_name_rdf);
-	if (canonical_key_name_rdf == NULL) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	canonical_algorithm_rdf = ldns_rdf_clone(algorithm_rdf);
-	if (canonical_algorithm_rdf == NULL) {
-		ldns_rdf_deep_free(canonical_key_name_rdf);
-		return LDNS_STATUS_MEM_ERR;
-	}
-	/*
-	 * prepare the digestable information
-	 */
-	data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
-	if (!data_buffer) {
-		status = LDNS_STATUS_MEM_ERR;
-		goto clean;
-	}
-	/* if orig_mac is not NULL, add it too */
-	if (orig_mac_rdf) {
-		(void) ldns_rdf2buffer_wire(data_buffer, orig_mac_rdf);
- 	}
-	ldns_buffer_write(data_buffer, pkt_wire, pkt_wire_size);
-	if (!tsig_timers_only) {
-		ldns_dname2canonical(canonical_key_name_rdf);
-		(void)ldns_rdf2buffer_wire(data_buffer, 
-				canonical_key_name_rdf);
-		ldns_buffer_write_u16(data_buffer, LDNS_RR_CLASS_ANY);
-		ldns_buffer_write_u32(data_buffer, 0);
-		ldns_dname2canonical(canonical_algorithm_rdf);
-		(void)ldns_rdf2buffer_wire(data_buffer, 
-				canonical_algorithm_rdf);
-	}
-	(void)ldns_rdf2buffer_wire(data_buffer, time_signed_rdf);
-	(void)ldns_rdf2buffer_wire(data_buffer, fudge_rdf);
-	if (!tsig_timers_only) {
-		(void)ldns_rdf2buffer_wire(data_buffer, error_rdf);
-		(void)ldns_rdf2buffer_wire(data_buffer, other_data_rdf);
-	}
-
-	wireformat = (char *) data_buffer->_data;
-	wiresize = (int) ldns_buffer_position(data_buffer);
-
-	algorithm_name = ldns_rdf2str(algorithm_rdf);
-	if(!algorithm_name) {
-		status = LDNS_STATUS_MEM_ERR;
-		goto clean;
-	}
-
-	/* prepare the key */
-	key_bytes = LDNS_XMALLOC(unsigned char,
-			ldns_b64_pton_calculate_size(strlen(key_data)));
-	if(!key_bytes) {
-		status = LDNS_STATUS_MEM_ERR;
-		goto clean;
-	}
-	key_size = ldns_b64_pton(key_data, key_bytes,
-	ldns_b64_pton_calculate_size(strlen(key_data)));
-	if (key_size < 0) {
-		status = LDNS_STATUS_INVALID_B64;
-		goto clean;
-	}
-	/* hmac it */
-	/* 2 spare bytes for the length */
-	mac_bytes = LDNS_XMALLOC(unsigned char, md_len+2);
-	if(!mac_bytes) {
-		status = LDNS_STATUS_MEM_ERR;
-		goto clean;
-	}
-	memset(mac_bytes, 0, md_len+2);
-
-	digester = ldns_digest_function(algorithm_name);
-
-	if (digester) {
-		(void) HMAC(digester, key_bytes, key_size, (void *)wireformat,
-		            (size_t) wiresize, mac_bytes + 2, &md_len);
-
-		ldns_write_uint16(mac_bytes, md_len);
-		result = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16_DATA, md_len + 2,
-				mac_bytes);
-	} else {
-		status = LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
-		goto clean;
-	}
-	*tsig_mac = result;
-	status = LDNS_STATUS_OK;
-  clean:
-	LDNS_FREE(mac_bytes);
-	LDNS_FREE(key_bytes);
-	LDNS_FREE(algorithm_name);
-	ldns_buffer_free(data_buffer);
-	ldns_rdf_deep_free(canonical_algorithm_rdf);
-	ldns_rdf_deep_free(canonical_key_name_rdf);
-	return status;
-}
-#endif /*  HAVE_SSL */
-
-
-#ifdef HAVE_SSL
-bool
-ldns_pkt_tsig_verify(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char *key_name,
-	const char *key_data, ldns_rdf *orig_mac_rdf)
-{
-	return ldns_pkt_tsig_verify_next(pkt, wire, wirelen, key_name, key_data, orig_mac_rdf, 0);
-}
-
-bool
-ldns_pkt_tsig_verify_next(ldns_pkt *pkt, uint8_t *wire, size_t wirelen, const char* key_name,
-	const char *key_data, ldns_rdf *orig_mac_rdf, int tsig_timers_only)
-{
-	ldns_rdf *fudge_rdf;
-	ldns_rdf *algorithm_rdf;
-	ldns_rdf *time_signed_rdf;
-	ldns_rdf *orig_id_rdf;
-	ldns_rdf *error_rdf;
-	ldns_rdf *other_data_rdf;
-	ldns_rdf *pkt_mac_rdf;
-	ldns_rdf *my_mac_rdf;
-	ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name);
-	uint16_t pkt_id, orig_pkt_id;
-	ldns_status status;
-
-	uint8_t *prepared_wire = NULL;
-	size_t prepared_wire_size = 0;
-
-	ldns_rr *orig_tsig = ldns_pkt_tsig(pkt);
-
-	if (!orig_tsig || ldns_rr_rd_count(orig_tsig) <= 6) {
-		ldns_rdf_deep_free(key_name_rdf);
-		return false;
-	}
-	algorithm_rdf = ldns_rr_rdf(orig_tsig, 0);
-	time_signed_rdf = ldns_rr_rdf(orig_tsig, 1);
-	fudge_rdf = ldns_rr_rdf(orig_tsig, 2);
-	pkt_mac_rdf = ldns_rr_rdf(orig_tsig, 3);
-	orig_id_rdf = ldns_rr_rdf(orig_tsig, 4);
-	error_rdf = ldns_rr_rdf(orig_tsig, 5);
-	other_data_rdf = ldns_rr_rdf(orig_tsig, 6);
-
-	/* remove temporarily */
-	ldns_pkt_set_tsig(pkt, NULL);
-	/* temporarily change the id to the original id */
-	pkt_id = ldns_pkt_id(pkt);
-	orig_pkt_id = ldns_rdf2native_int16(orig_id_rdf);
-	ldns_pkt_set_id(pkt, orig_pkt_id);
-
-	prepared_wire = ldns_tsig_prepare_pkt_wire(wire, wirelen, &prepared_wire_size);
-
-	status = ldns_tsig_mac_new(&my_mac_rdf, prepared_wire, prepared_wire_size,
-			key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
-			time_signed_rdf, error_rdf, other_data_rdf, orig_mac_rdf, tsig_timers_only);
-
-	LDNS_FREE(prepared_wire);
-
-	if (status != LDNS_STATUS_OK) {
-		ldns_rdf_deep_free(key_name_rdf);
-		return false;
-	}
-	/* Put back the values */
-	ldns_pkt_set_tsig(pkt, orig_tsig);
-	ldns_pkt_set_id(pkt, pkt_id);
-
-	ldns_rdf_deep_free(key_name_rdf);
-
-	if (ldns_rdf_compare(pkt_mac_rdf, my_mac_rdf) == 0) {
-		ldns_rdf_deep_free(my_mac_rdf);
-		return true;
-	} else {
-		ldns_rdf_deep_free(my_mac_rdf);
-		return false;
-	}
-}
-#endif /* HAVE_SSL */
-
-#ifdef HAVE_SSL
-ldns_status
-ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data,
-	uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac)
-{
-	return ldns_pkt_tsig_sign_next(pkt, key_name, key_data, fudge, algorithm_name, query_mac, 0);
-}
-
-ldns_status
-ldns_pkt_tsig_sign_next(ldns_pkt *pkt, const char *key_name, const char *key_data,
-	uint16_t fudge, const char *algorithm_name, ldns_rdf *query_mac, int tsig_timers_only)
-{
-	ldns_rr *tsig_rr;
-	ldns_rdf *key_name_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, key_name);
-	ldns_rdf *fudge_rdf = NULL;
-	ldns_rdf *orig_id_rdf = NULL;
-	ldns_rdf *algorithm_rdf;
-	ldns_rdf *error_rdf = NULL;
-	ldns_rdf *mac_rdf = NULL;
-	ldns_rdf *other_data_rdf = NULL;
-
-	ldns_status status = LDNS_STATUS_OK;
-
-	uint8_t *pkt_wire = NULL;
-	size_t pkt_wire_len;
-
-	struct timeval tv_time_signed;
-	uint8_t *time_signed = NULL;
-	ldns_rdf *time_signed_rdf = NULL;
-
-	algorithm_rdf = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, algorithm_name);
-	if(!key_name_rdf || !algorithm_rdf) {
-		status = LDNS_STATUS_MEM_ERR;
-		goto clean;
-	}
-
-	/* eww don't have create tsigtime rdf yet :( */
-	/* bleh :p */
-	if (gettimeofday(&tv_time_signed, NULL) == 0) {
-		time_signed = LDNS_XMALLOC(uint8_t, 6);
-		if(!time_signed) {
-			status = LDNS_STATUS_MEM_ERR;
-			goto clean;
-		}
-		ldns_write_uint64_as_uint48(time_signed,
-				(uint64_t)tv_time_signed.tv_sec);
-	} else {
-		status = LDNS_STATUS_INTERNAL_ERR;
-		goto clean;
-	}
-
-	time_signed_rdf = ldns_rdf_new(LDNS_RDF_TYPE_TSIGTIME, 6, time_signed);
-	if(!time_signed_rdf) {
-		LDNS_FREE(time_signed);
-		status = LDNS_STATUS_MEM_ERR;
-		goto clean;
-	}
-
-	fudge_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, fudge);
-
-	orig_id_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, ldns_pkt_id(pkt));
-
-	error_rdf = ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 0);
-
-	other_data_rdf = ldns_native2rdf_int16_data(0, NULL);
-
-	if(!fudge_rdf || !orig_id_rdf || !error_rdf || !other_data_rdf) {
-		status = LDNS_STATUS_MEM_ERR;
-		goto clean;
-	}
-
-	if (ldns_pkt2wire(&pkt_wire, pkt, &pkt_wire_len) != LDNS_STATUS_OK) {
-		status = LDNS_STATUS_ERR;
-		goto clean;
-	}
-
-	status = ldns_tsig_mac_new(&mac_rdf, pkt_wire, pkt_wire_len,
-			key_data, key_name_rdf, fudge_rdf, algorithm_rdf,
-			time_signed_rdf, error_rdf, other_data_rdf, query_mac, tsig_timers_only);
-
-	if (!mac_rdf) {
-		goto clean;
-	}
-
-	LDNS_FREE(pkt_wire);
-
-	/* Create the TSIG RR */
-	tsig_rr = ldns_rr_new();
-	if(!tsig_rr) {
-		status = LDNS_STATUS_MEM_ERR;
-		goto clean;
-	}
-	ldns_rr_set_owner(tsig_rr, key_name_rdf);
-	ldns_rr_set_class(tsig_rr, LDNS_RR_CLASS_ANY);
-	ldns_rr_set_type(tsig_rr, LDNS_RR_TYPE_TSIG);
-	ldns_rr_set_ttl(tsig_rr, 0);
-
-	ldns_rr_push_rdf(tsig_rr, algorithm_rdf);
-	ldns_rr_push_rdf(tsig_rr, time_signed_rdf);
-	ldns_rr_push_rdf(tsig_rr, fudge_rdf);
-	ldns_rr_push_rdf(tsig_rr, mac_rdf);
-	ldns_rr_push_rdf(tsig_rr, orig_id_rdf);
-	ldns_rr_push_rdf(tsig_rr, error_rdf);
-	ldns_rr_push_rdf(tsig_rr, other_data_rdf);
-
-	ldns_pkt_set_tsig(pkt, tsig_rr);
-
-	return status;
-
-  clean:
-	LDNS_FREE(pkt_wire);
-	ldns_rdf_free(key_name_rdf);
-	ldns_rdf_free(algorithm_rdf);
-	ldns_rdf_free(time_signed_rdf);
-	ldns_rdf_free(fudge_rdf);
-	ldns_rdf_free(orig_id_rdf);
-	ldns_rdf_free(error_rdf);
-	ldns_rdf_free(other_data_rdf);
-	return status;
-}
-#endif /* HAVE_SSL */
diff --git a/src/ldns/update.c b/src/ldns/update.c
deleted file mode 100644
index 74e9d19..0000000
--- a/src/ldns/update.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/* update.c
- *
- * Functions for RFC 2136 Dynamic Update
- *
- * Copyright (c) 2005-2008, NLnet Labs. All rights reserved.
- *
- * See LICENSE for the license.
- */
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <strings.h>
-#include <stdlib.h>
-#include <limits.h>
-
-/*
- * RFC 2136 sections mapped to RFC 1035:
- *              zone/ZO -- QD/question
- *     prerequisites/PR -- AN/answers
- *           updates/UP -- NS/authority records
- *   additional data/AD -- AR/additional records
- */
-
-ldns_pkt *
-ldns_update_pkt_new(ldns_rdf *zone_rdf, ldns_rr_class c,
-    ldns_rr_list *pr_rrlist, ldns_rr_list *up_rrlist, ldns_rr_list *ad_rrlist)
-{
-	ldns_pkt *p;
-
-	if (!zone_rdf || !up_rrlist) {
-		return NULL;
-	}
-
-	if (c == 0) { 
-		c = LDNS_RR_CLASS_IN;
-	}
-
-	/* Create packet, fill in Zone Section. */
-	p = ldns_pkt_query_new(zone_rdf, LDNS_RR_TYPE_SOA, c, LDNS_RD);
-	if (!p) {
-		return NULL;
-	}
-	zone_rdf = NULL; /* No longer safe to use. */
-
-	ldns_pkt_set_opcode(p, LDNS_PACKET_UPDATE);
-
-	ldns_rr_list_deep_free(p->_authority);
-
-	ldns_pkt_set_authority(p, ldns_rr_list_clone(up_rrlist));
-
-	ldns_update_set_upcount(p, ldns_rr_list_rr_count(up_rrlist));
-
-	if (pr_rrlist) {
-		ldns_rr_list_deep_free(p->_answer); /*XXX access function */
-		ldns_pkt_set_answer(p, ldns_rr_list_clone(pr_rrlist));
-		ldns_update_set_prcount(p, ldns_rr_list_rr_count(pr_rrlist));
-	}
-
-	if (ad_rrlist) {
-		ldns_rr_list_deep_free(p->_additional);
-		ldns_pkt_set_additional(p, ldns_rr_list_clone(ad_rrlist));
-		ldns_update_set_adcount(p, ldns_rr_list_rr_count(ad_rrlist));
-	}
-	return p;
-}
-
-ldns_status
-ldns_update_pkt_tsig_add(ldns_pkt *p, ldns_resolver *r)
-{
-#ifdef HAVE_SSL
-	uint16_t fudge = 300; /* Recommended fudge. [RFC2845 6.4]  */
-	if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r))
-		return ldns_pkt_tsig_sign(p, ldns_resolver_tsig_keyname(r),
-		    ldns_resolver_tsig_keydata(r), fudge,
-		    ldns_resolver_tsig_algorithm(r), NULL);
-#else
-	/* do nothing */
-	(void)p;
-	(void)r;
-#endif /* HAVE_SSL */
-	/* No TSIG to do. */
-	return LDNS_STATUS_OK;
-}
-
-/* Move to higher.c or similar? */
-/* XXX doc */
-ldns_status
-ldns_update_soa_mname(ldns_rdf *zone, ldns_resolver *r,
-    ldns_rr_class c, ldns_rdf **mname)
-{
-	ldns_rr		*soa_rr;
-	ldns_pkt	*query, *resp;
-
-	/* Nondestructive, so clone 'zone' here */
-	query = ldns_pkt_query_new(ldns_rdf_clone(zone), LDNS_RR_TYPE_SOA,
-	    c, LDNS_RD);
-	if (!query) {
-		return LDNS_STATUS_ERR;
-	}
-
-	ldns_pkt_set_random_id(query);
-	if (ldns_resolver_send_pkt(&resp, r, query) != LDNS_STATUS_OK) {
-		ldns_pkt_free(query);
-		return LDNS_STATUS_ERR;
-	}
-	ldns_pkt_free(query);
-	if (!resp) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* Expect a SOA answer. */
-	*mname = NULL;
-	while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_answer(resp)))) {
-		if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
-				|| ldns_rr_rdf(soa_rr, 0) == NULL)
-			continue;
-		/* [RFC1035 3.3.13] */
-		*mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
-		break;
-	}
-	ldns_pkt_free(resp);
-
-	return *mname ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
-}
-
-/* Try to get zone and MNAME from SOA queries. */
-ldns_status
-ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r,
-    ldns_rr_class c, ldns_rdf **zone_rdf, ldns_rdf **mname_rdf)
-{
-	ldns_rr		*soa_rr, *rr;
-	ldns_rdf	*soa_zone = NULL, *soa_mname = NULL;
-	ldns_rdf	*ipaddr, *fqdn_rdf, *tmp;
-	ldns_rdf	**nslist;
-	ldns_pkt	*query, *resp;
-	ldns_resolver   *tmp_r;
-	size_t		i;
-
-	/* 
-	 * XXX Ok, this cannot be the best way to find this...?
-	 * XXX (I run into weird cache-related stuff here)
-	 */
-
-	/* Step 1 - first find a nameserver that should know *something* */
-	fqdn_rdf = ldns_dname_new_frm_str(fqdn);
-	query = ldns_pkt_query_new(fqdn_rdf, LDNS_RR_TYPE_SOA, c, LDNS_RD);
-	if (!query) {
-		return LDNS_STATUS_ERR;
-	}
-	fqdn_rdf = NULL;
-
-	ldns_pkt_set_random_id(query);
-	if (ldns_resolver_send_pkt(&resp, r, query) != LDNS_STATUS_OK) {
-		ldns_pkt_free(query);
-		return LDNS_STATUS_ERR;
-	}
-	ldns_pkt_free(query);
-	if (!resp) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* XXX Is it safe to only look in authority section here? */
-	while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
-		if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
-				|| ldns_rr_rdf(soa_rr, 0) == NULL)
-			continue;
-		/* [RFC1035 3.3.13] */
-		soa_mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
-		break;
-	}
-	ldns_pkt_free(resp);
-	if (!soa_rr) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* Step 2 - find SOA MNAME IP address, add to resolver */
-	query = ldns_pkt_query_new(soa_mname, LDNS_RR_TYPE_A, c, LDNS_RD);
-	if (!query) {
-		return LDNS_STATUS_ERR;
-	}
-	soa_mname = NULL;
-
-	ldns_pkt_set_random_id(query);
-	if (ldns_resolver_send_pkt(&resp, r, query) != LDNS_STATUS_OK) {
-		ldns_pkt_free(query);
-		return LDNS_STATUS_ERR;
-	}
-	ldns_pkt_free(query);
-	if (!resp) {
-		return LDNS_STATUS_ERR;
-	}
-
-	if (ldns_pkt_ancount(resp) == 0) {
-		ldns_pkt_free(resp);
-		return LDNS_STATUS_ERR;
-	}
-
-	/* XXX There may be more than one answer RR here. */
-	rr = ldns_rr_list_pop_rr(ldns_pkt_answer(resp));
-	ipaddr = ldns_rr_rdf(rr, 0);
-
-	/* Put the SOA mname IP first in the nameserver list. */
-	if (!(tmp_r = ldns_resolver_clone(r))) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	nslist = ldns_resolver_nameservers(tmp_r);
-	for (i = 0; i < ldns_resolver_nameserver_count(tmp_r); i++) {
-		if (ldns_rdf_compare(ipaddr, nslist[i]) == 0) {
-			if (i) {
-				tmp = nslist[0];
-				nslist[0] = nslist[i];
-				nslist[i] = tmp;
-			}
-			break;
-		}
-	}
-	if (i >= ldns_resolver_nameserver_count(tmp_r)) {
-		/* SOA mname was not part of the resolver so add it first. */
-		(void) ldns_resolver_push_nameserver(tmp_r, ipaddr);
-		nslist = ldns_resolver_nameservers(tmp_r);
-		i = ldns_resolver_nameserver_count(tmp_r) - 1;
-		tmp = nslist[0];
-		nslist[0] = nslist[i];
-		nslist[i] = tmp;
-	}
-	ldns_pkt_free(resp);
-
-	/* Make sure to ask the first in the list, i.e SOA mname */
-	ldns_resolver_set_random(tmp_r, false);
-
-	/* Step 3 - Redo SOA query, sending to SOA MNAME directly. */
-	fqdn_rdf = ldns_dname_new_frm_str(fqdn);
-	query = ldns_pkt_query_new(fqdn_rdf, LDNS_RR_TYPE_SOA, c, LDNS_RD);
-	if (!query) {
-		ldns_resolver_free(tmp_r);
-		return LDNS_STATUS_ERR;
-	}
-	fqdn_rdf = NULL;
-
-	ldns_pkt_set_random_id(query);
-	if (ldns_resolver_send_pkt(&resp, tmp_r, query) != LDNS_STATUS_OK) {
-		ldns_pkt_free(query);
-		ldns_resolver_free(tmp_r);
-		return LDNS_STATUS_ERR;
-	}
-	ldns_resolver_free(tmp_r);
-	ldns_pkt_free(query);
-	if (!resp) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* XXX Is it safe to only look in authority section here, too? */
-	while ((soa_rr = ldns_rr_list_pop_rr(ldns_pkt_authority(resp)))) {
-		if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
-				|| ldns_rr_rdf(soa_rr, 0) == NULL)
-			continue;
-		/* [RFC1035 3.3.13] */
-		soa_mname = ldns_rdf_clone(ldns_rr_rdf(soa_rr, 0));
-		soa_zone = ldns_rdf_clone(ldns_rr_owner(soa_rr));
-		break;
-	}
-	ldns_pkt_free(resp);
-	if (!soa_rr) {
-		return LDNS_STATUS_ERR;
-	}
-
-	/* That seems to have worked, pass results to caller. */
-	*zone_rdf = soa_zone;
-	*mname_rdf = soa_mname;
-	return LDNS_STATUS_OK;
-}	
-
-/*
- * ldns_update_{get,set}_{zo,pr,up,ad}count
- */
-
-uint16_t
-ldns_update_zocount(const ldns_pkt *p)
-{
-	return ldns_pkt_qdcount(p);
-}
-
-uint16_t
-ldns_update_prcount(const ldns_pkt *p)
-{
-	return ldns_pkt_ancount(p);
-}
-
-uint16_t
-ldns_update_upcount(const ldns_pkt *p)
-{
-	return ldns_pkt_nscount(p);
-}
-
-uint16_t
-ldns_update_ad(const ldns_pkt *p)
-{
-	return ldns_pkt_arcount(p);
-}
-
-void
-ldns_update_set_zo(ldns_pkt *p, uint16_t v)
-{
-	ldns_pkt_set_qdcount(p, v);
-}
-
-void
-ldns_update_set_prcount(ldns_pkt *p, uint16_t v)
-{
-	ldns_pkt_set_ancount(p, v);
-}
-
-void
-ldns_update_set_upcount(ldns_pkt *p, uint16_t v)
-{
-	ldns_pkt_set_nscount(p, v);
-}
-
-void
-ldns_update_set_adcount(ldns_pkt *p, uint16_t v)
-{
-	ldns_pkt_set_arcount(p, v);
-}
diff --git a/src/ldns/util.c b/src/ldns/util.c
deleted file mode 100644
index 33060d9..0000000
--- a/src/ldns/util.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * util.c
- *
- * some general memory functions
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-#include <ldns/config.h>
-
-#include <ldns/rdata.h>
-#include <ldns/rr.h>
-#include <ldns/util.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <time.h>
-#include <ctype.h>
-
-#ifdef HAVE_SSL
-#include <openssl/rand.h>
-#endif
-
-ldns_lookup_table *
-ldns_lookup_by_name(ldns_lookup_table *table, const char *name)
-{
-	while (table->name != NULL) {
-		if (strcasecmp(name, table->name) == 0)
-			return table;
-		table++;
-	}
-	return NULL;
-}
-
-ldns_lookup_table *
-ldns_lookup_by_id(ldns_lookup_table *table, int id)
-{
-	while (table->name != NULL) {
-		if (table->id == id)
-			return table;
-		table++;
-	}
-	return NULL;
-}
-
-int
-ldns_get_bit(uint8_t bits[], size_t index)
-{
-	/*
-	 * The bits are counted from left to right, so bit #0 is the
-	 * left most bit.
-	 */
-	return (int) (bits[index / 8] & (1 << (7 - index % 8)));
-}
-
-int
-ldns_get_bit_r(uint8_t bits[], size_t index)
-{
-	/*
-	 * The bits are counted from right to left, so bit #0 is the
-	 * right most bit.
-	 */
-	return (int) bits[index / 8] & (1 << (index % 8));
-}
-
-void
-ldns_set_bit(uint8_t *byte, int bit_nr, bool value)
-{
-	/*
-	 * The bits are counted from right to left, so bit #0 is the
-	 * right most bit.
-	 */
-	if (bit_nr >= 0 && bit_nr < 8) {
-		if (value) {
-			*byte = *byte | (0x01 << bit_nr);
-		} else {
-			*byte = *byte & ~(0x01 << bit_nr);
-		}
-	}
-}
-
-int
-ldns_hexdigit_to_int(char ch)
-{
-	switch (ch) {
-	case '0': return 0;
-	case '1': return 1;
-	case '2': return 2;
-	case '3': return 3;
-	case '4': return 4;
-	case '5': return 5;
-	case '6': return 6;
-	case '7': return 7;
-	case '8': return 8;
-	case '9': return 9;
-	case 'a': case 'A': return 10;
-	case 'b': case 'B': return 11;
-	case 'c': case 'C': return 12;
-	case 'd': case 'D': return 13;
-	case 'e': case 'E': return 14;
-	case 'f': case 'F': return 15;
-	default:
-		return -1;
-	}
-}
-
-char
-ldns_int_to_hexdigit(int i)
-{
-	switch (i) {
-	case 0: return '0';
-	case 1: return '1';
-	case 2: return '2';
-	case 3: return '3';
-	case 4: return '4';
-	case 5: return '5';
-	case 6: return '6';
-	case 7: return '7';
-	case 8: return '8';
-	case 9: return '9';
-	case 10: return 'a';
-	case 11: return 'b';
-	case 12: return 'c';
-	case 13: return 'd';
-	case 14: return 'e';
-	case 15: return 'f';
-	default:
-		abort();
-	}
-}
-
-int
-ldns_hexstring_to_data(uint8_t *data, const char *str)
-{
-	size_t i;
-
-	if (!str || !data) {
-		return -1;
-	}
-
-	if (strlen(str) % 2 != 0) {
-		return -2;
-	}
-
-	for (i = 0; i < strlen(str) / 2; i++) {
-		data[i] =
-			16 * (uint8_t) ldns_hexdigit_to_int(str[i*2]) +
-			(uint8_t) ldns_hexdigit_to_int(str[i*2 + 1]);
-	}
-
-	return (int) i;
-}
-
-const char *
-ldns_version(void)
-{
-	return (char*)LDNS_VERSION;
-}
-
-/* Number of days per month (except for February in leap years). */
-static const int mdays[] = {
-	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-#define LDNS_MOD(x,y) (((x) % (y) < 0) ? ((x) % (y) + (y)) : ((x) % (y)))
-#define LDNS_DIV(x,y) (((x) % (y) < 0) ? ((x) / (y) -  1 ) : ((x) / (y)))
-
-static int
-is_leap_year(int year)
-{
-	return LDNS_MOD(year,   4) == 0 && (LDNS_MOD(year, 100) != 0 
-	    || LDNS_MOD(year, 400) == 0);
-}
-
-static int
-leap_days(int y1, int y2)
-{
-	--y1;
-	--y2;
-	return (LDNS_DIV(y2,   4) - LDNS_DIV(y1,   4)) - 
-	       (LDNS_DIV(y2, 100) - LDNS_DIV(y1, 100)) +
-	       (LDNS_DIV(y2, 400) - LDNS_DIV(y1, 400));
-}
-
-/*
- * Code adapted from Python 2.4.1 sources (Lib/calendar.py).
- */
-time_t
-ldns_mktime_from_utc(const struct tm *tm)
-{
-	int year = 1900 + tm->tm_year;
-	time_t days = 365 * ((time_t) year - 1970) + leap_days(1970, year);
-	time_t hours;
-	time_t minutes;
-	time_t seconds;
-	int i;
-
-	for (i = 0; i < tm->tm_mon; ++i) {
-		days += mdays[i];
-	}
-	if (tm->tm_mon > 1 && is_leap_year(year)) {
-		++days;
-	}
-	days += tm->tm_mday - 1;
-
-	hours = days * 24 + tm->tm_hour;
-	minutes = hours * 60 + tm->tm_min;
-	seconds = minutes * 60 + tm->tm_sec;
-
-	return seconds;
-}
-
-time_t
-mktime_from_utc(const struct tm *tm)
-{
-	return ldns_mktime_from_utc(tm);
-}
-
-#if SIZEOF_TIME_T <= 4
-
-static void
-ldns_year_and_yday_from_days_since_epoch(int64_t days, struct tm *result)
-{
-	int year = 1970;
-	int new_year;
-
-	while (days < 0 || days >= (int64_t) (is_leap_year(year) ? 366 : 365)) {
-		new_year = year + (int) LDNS_DIV(days, 365);
-		days -= (new_year - year) * 365;
-		days -= leap_days(year, new_year);
-		year  = new_year;
-	}
-	result->tm_year = year;
-	result->tm_yday = (int) days;
-}
-
-/* Number of days per month in a leap year. */
-static const int leap_year_mdays[] = {
-	31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-static void
-ldns_mon_and_mday_from_year_and_yday(struct tm *result)
-{
-	int idays = result->tm_yday;
-	const int *mon_lengths = is_leap_year(result->tm_year) ? 
-					leap_year_mdays : mdays;
-
-	result->tm_mon = 0;
-	while  (idays >= mon_lengths[result->tm_mon]) {
-		idays -= mon_lengths[result->tm_mon++];
-	}
-	result->tm_mday = idays + 1;
-}
-
-static void
-ldns_wday_from_year_and_yday(struct tm *result)
-{
-	result->tm_wday = 4 /* 1-1-1970 was a thursday */
-			+ LDNS_MOD((result->tm_year - 1970), 7) * LDNS_MOD(365, 7)
-			+ leap_days(1970, result->tm_year)
-			+ result->tm_yday;
-	result->tm_wday = LDNS_MOD(result->tm_wday, 7);
-	if (result->tm_wday < 0) {
-		result->tm_wday += 7;
-	}
-}
-
-static struct tm *
-ldns_gmtime64_r(int64_t clock, struct tm *result)
-{
-	result->tm_isdst = 0;
-	result->tm_sec   = (int) LDNS_MOD(clock, 60);
-	clock            =       LDNS_DIV(clock, 60);
-	result->tm_min   = (int) LDNS_MOD(clock, 60);
-	clock            =       LDNS_DIV(clock, 60);
-	result->tm_hour  = (int) LDNS_MOD(clock, 24);
-	clock            =       LDNS_DIV(clock, 24);
-
-	ldns_year_and_yday_from_days_since_epoch(clock, result);
-	ldns_mon_and_mday_from_year_and_yday(result);
-	ldns_wday_from_year_and_yday(result);
-	result->tm_year -= 1900;
-
-	return result;
-}
-
-#endif /* SIZEOF_TIME_T <= 4 */
-
-static int64_t
-ldns_serial_arithmitics_time(int32_t time, time_t now)
-{
-	int32_t offset = time - (int32_t) now;
-	return (int64_t) now + offset;
-}
-
-
-struct tm *
-ldns_serial_arithmitics_gmtime_r(int32_t time, time_t now, struct tm *result)
-{
-#if SIZEOF_TIME_T <= 4
-	int64_t secs_since_epoch = ldns_serial_arithmitics_time(time, now);
-	return  ldns_gmtime64_r(secs_since_epoch, result);
-#else
-	time_t  secs_since_epoch = ldns_serial_arithmitics_time(time, now);
-	return  gmtime_r(&secs_since_epoch, result);
-#endif
-}
-
-/**
- * Init the random source
- * applications should call this if they need entropy data within ldns
- * If openSSL is available, it is automatically seeded from /dev/urandom
- * or /dev/random
- *
- * If you need more entropy, or have no openssl available, this function
- * MUST be called at the start of the program
- *
- * If openssl *is* available, this function just adds more entropy
- **/
-int
-ldns_init_random(FILE *fd, unsigned int size)
-{
-	/* if fp is given, seed srandom with data from file
-	   otherwise use /dev/urandom */
-	FILE *rand_f;
-	uint8_t *seed;
-	size_t read = 0;
-	unsigned int seed_i;
-	struct timeval tv;
-
-	/* we'll need at least sizeof(unsigned int) bytes for the
-	   standard prng seed */
-	if (size < (unsigned int) sizeof(seed_i)){
-		size = (unsigned int) sizeof(seed_i);
-	}
-
-	seed = LDNS_XMALLOC(uint8_t, size);
-        if(!seed) {
-		return 1;
-        }
-
-	if (!fd) {
-		if ((rand_f = fopen("/dev/urandom", "r")) == NULL) {
-			/* no readable /dev/urandom, try /dev/random */
-			if ((rand_f = fopen("/dev/random", "r")) == NULL) {
-				/* no readable /dev/random either, and no entropy
-				   source given. we'll have to improvise */
-				for (read = 0; read < size; read++) {
-					gettimeofday(&tv, NULL);
-					seed[read] = (uint8_t) (tv.tv_usec % 256);
-				}
-			} else {
-				read = fread(seed, 1, size, rand_f);
-			}
-		} else {
-			read = fread(seed, 1, size, rand_f);
-		}
-	} else {
-		rand_f = fd;
-		read = fread(seed, 1, size, rand_f);
-	}
-
-	if (read < size) {
-		LDNS_FREE(seed);
-		if (!fd) fclose(rand_f);
-		return 1;
-	} else {
-#ifdef HAVE_SSL
-		/* Seed the OpenSSL prng (most systems have it seeded
-		   automatically, in that case this call just adds entropy */
-		RAND_seed(seed, (int) size);
-#else
-		/* Seed the standard prng, only uses the first
-		 * unsigned sizeof(unsiged int) bytes found in the entropy pool
-		 */
-		memcpy(&seed_i, seed, sizeof(seed_i));
-		srandom(seed_i);
-#endif
-		LDNS_FREE(seed);
-	}
-
-	if (!fd) {
-                if (rand_f) fclose(rand_f);
-	}
-
-	return 0;
-}
-
-/**
- * Get random number.
- *
- */
-uint16_t
-ldns_get_random(void)
-{
-        uint16_t rid = 0;
-#ifdef HAVE_SSL
-        if (RAND_bytes((unsigned char*)&rid, 2) != 1) {
-                rid = (uint16_t) random();
-        }
-#else
-        rid = (uint16_t) random();
-#endif
-	return rid;
-}
-
-/*
- * BubbleBabble code taken from OpenSSH
- * Copyright (c) 2001 Carsten Raskgaard.  All rights reserved.
- */
-char *
-ldns_bubblebabble(uint8_t *data, size_t len)
-{
-	char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
-	char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
-	    'n', 'p', 'r', 's', 't', 'v', 'z', 'x' };
-	size_t i, j = 0, rounds, seed = 1;
-	char *retval;
-
-	rounds = (len / 2) + 1;
-	retval = LDNS_XMALLOC(char, rounds * 6);
-	if(!retval) return NULL;
-	retval[j++] = 'x';
-	for (i = 0; i < rounds; i++) {
-		size_t idx0, idx1, idx2, idx3, idx4;
-		if ((i + 1 < rounds) || (len % 2 != 0)) {
-			idx0 = (((((size_t)(data[2 * i])) >> 6) & 3) +
-			    seed) % 6;
-			idx1 = (((size_t)(data[2 * i])) >> 2) & 15;
-			idx2 = ((((size_t)(data[2 * i])) & 3) +
-			    (seed / 6)) % 6;
-			retval[j++] = vowels[idx0];
-			retval[j++] = consonants[idx1];
-			retval[j++] = vowels[idx2];
-			if ((i + 1) < rounds) {
-				idx3 = (((size_t)(data[(2 * i) + 1])) >> 4) & 15;
-				idx4 = (((size_t)(data[(2 * i) + 1]))) & 15;
-				retval[j++] = consonants[idx3];
-				retval[j++] = '-';
-				retval[j++] = consonants[idx4];
-				seed = ((seed * 5) +
-				    ((((size_t)(data[2 * i])) * 7) +
-				    ((size_t)(data[(2 * i) + 1])))) % 36;
-			}
-		} else {
-			idx0 = seed % 6;
-			idx1 = 16;
-			idx2 = seed / 6;
-			retval[j++] = vowels[idx0];
-			retval[j++] = consonants[idx1];
-			retval[j++] = vowels[idx2];
-		}
-	}
-	retval[j++] = 'x';
-	retval[j++] = '\0';
-	return retval;
-}
-
-/*
- * For backwards compatibility, because we have always exported this symbol.
- */
-#ifdef HAVE_B64_NTOP
-int ldns_b64_ntop(const uint8_t* src, size_t srclength,
-		char *target, size_t targsize);
-{
-	return b64_ntop(src, srclength, target, targsize);
-}
-#endif
-
-/*
- * For backwards compatibility, because we have always exported this symbol.
- */
-#ifdef HAVE_B64_PTON
-int ldns_b64_pton(const char* src, uint8_t *target, size_t targsize)
-{
-	return b64_pton(src, target, targsize);
-}
-#endif
-
-
-static int
-ldns_b32_ntop_base(const uint8_t* src, size_t src_sz,
-		char* dst, size_t dst_sz,
-		bool extended_hex, bool add_padding)
-{
-	size_t ret_sz;
-	const char* b32 = extended_hex ? "0123456789abcdefghijklmnopqrstuv"
-	                               : "abcdefghijklmnopqrstuvwxyz234567";
-
-	size_t c = 0; /* c is used to carry partial base32 character over 
-	               * byte boundaries for sizes with a remainder.
-		       * (i.e. src_sz % 5 != 0)
-		       */
-
-	ret_sz = add_padding ? ldns_b32_ntop_calculate_size(src_sz)
-	                     : ldns_b32_ntop_calculate_size_no_padding(src_sz);
-	
-	/* Do we have enough space? */
-	if (dst_sz < ret_sz + 1)
-		return -1;
-
-	/* We know the size; terminate the string */
-	dst[ret_sz] = '\0';
-
-	/* First process all chunks of five */
-	while (src_sz >= 5) {
-		/* 00000... ........ ........ ........ ........ */
-		dst[0] = b32[(src[0]       ) >> 3];
-
-		/* .....111 11...... ........ ........ ........ */
-		dst[1] = b32[(src[0] & 0x07) << 2 | src[1] >> 6];
-
-		/* ........ ..22222. ........ ........ ........ */
-		dst[2] = b32[(src[1] & 0x3e) >> 1];
-
-		/* ........ .......3 3333.... ........ ........ */
-		dst[3] = b32[(src[1] & 0x01) << 4 | src[2] >> 4];
-
-		/* ........ ........ ....4444 4....... ........ */
-		dst[4] = b32[(src[2] & 0x0f) << 1 | src[3] >> 7];
-
-		/* ........ ........ ........ .55555.. ........ */
-		dst[5] = b32[(src[3] & 0x7c) >> 2];
-
-		/* ........ ........ ........ ......66 666..... */
-		dst[6] = b32[(src[3] & 0x03) << 3 | src[4] >> 5];
-
-		/* ........ ........ ........ ........ ...77777 */
-		dst[7] = b32[(src[4] & 0x1f)     ];
-
-		src_sz -= 5;
-		src    += 5;
-		dst    += 8;
-	}
-	/* Process what remains */
-	switch (src_sz) {
-	case 4: /* ........ ........ ........ ......66 666..... */
-		dst[6] = b32[(src[3] & 0x03) << 3];
-
-		/* ........ ........ ........ .55555.. ........ */
-		dst[5] = b32[(src[3] & 0x7c) >> 2];
-
-		/* ........ ........ ....4444 4....... ........ */
-		         c =  src[3]         >> 7 ;
-	case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
-
-		/* ........ .......3 3333.... ........ ........ */
-			 c =  src[2]         >> 4 ;
-	case 2:	dst[3] = b32[(src[1] & 0x01) << 4 | c];
-
-		/* ........ ..22222. ........ ........ ........ */
-		dst[2] = b32[(src[1] & 0x3e) >> 1];
-
-		/* .....111 11...... ........ ........ ........ */
-	                 c =  src[1]         >> 6 ;
-	case 1:	dst[1] = b32[(src[0] & 0x07) << 2 | c];
-
-		/* 00000... ........ ........ ........ ........ */
-		dst[0] = b32[ src[0]         >> 3];
-	}
-	/* Add padding */
-	if (add_padding) {
-		switch (src_sz) {
-			case 1: dst[2] = '=';
-				dst[3] = '=';
-			case 2: dst[4] = '=';
-			case 3: dst[5] = '=';
-				dst[6] = '=';
-			case 4: dst[7] = '=';
-		}
-	}
-	return (int)ret_sz;
-}
-
-int 
-ldns_b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz)
-{
-	return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, false, true);
-}
-
-int 
-ldns_b32_ntop_extended_hex(const uint8_t* src, size_t src_sz,
-		char* dst, size_t dst_sz)
-{
-	return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, true, true);
-}
-
-#ifndef HAVE_B32_NTOP
-
-int 
-b32_ntop(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz)
-{
-	return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, false, true);
-}
-
-int 
-b32_ntop_extended_hex(const uint8_t* src, size_t src_sz,
-		char* dst, size_t dst_sz)
-{
-	return ldns_b32_ntop_base(src, src_sz, dst, dst_sz, true, true);
-}
-
-#endif /* ! HAVE_B32_NTOP */
-
-static int
-ldns_b32_pton_base(const char* src, size_t src_sz,
-		uint8_t* dst, size_t dst_sz,
-		bool extended_hex, bool check_padding)
-{
-	size_t i = 0;
-	char ch = '\0';
-	uint8_t buf[8];
-	uint8_t* start = dst;
-
-	while (src_sz) {
-		/* Collect 8 characters in buf (if possible) */
-		for (i = 0; i < 8; i++) {
-
-			do {
-				ch = *src++;
-				--src_sz;
-
-			} while (isspace(ch) && src_sz > 0);
-
-			if (ch == '=' || ch == '\0')
-				break;
-
-			else if (extended_hex)
-
-				if (ch >= '0' && ch <= '9')
-					buf[i] = (uint8_t)ch - '0';
-				else if (ch >= 'a' && ch <= 'v')
-					buf[i] = (uint8_t)ch - 'a' + 10;
-				else if (ch >= 'A' && ch <= 'V')
-					buf[i] = (uint8_t)ch - 'A' + 10;
-				else
-					return -1;
-
-			else if (ch >= 'a' && ch <= 'z')
-				buf[i] = (uint8_t)ch - 'a';
-			else if (ch >= 'A' && ch <= 'Z')
-				buf[i] = (uint8_t)ch - 'A';
-			else if (ch >= '2' && ch <= '7')
-				buf[i] = (uint8_t)ch - '2' + 26;
-			else
-				return -1;
-		}
-		/* Less that 8 characters. We're done. */
-		if (i < 8)
-			break;
-
-		/* Enough space available at the destination? */
-		if (dst_sz < 5)
-			return -1;
-
-		/* 00000... ........ ........ ........ ........ */
-		/* .....111 11...... ........ ........ ........ */
-		dst[0] = buf[0] << 3 | buf[1] >> 2;
-
-		/* .....111 11...... ........ ........ ........ */
-		/* ........ ..22222. ........ ........ ........ */
-		/* ........ .......3 3333.... ........ ........ */
-		dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
-
-		/* ........ .......3 3333.... ........ ........ */
-		/* ........ ........ ....4444 4....... ........ */
-		dst[2] = buf[3] << 4 | buf[4] >> 1;
-
-		/* ........ ........ ....4444 4....... ........ */
-		/* ........ ........ ........ .55555.. ........ */
-		/* ........ ........ ........ ......66 666..... */
-		dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
-
-		/* ........ ........ ........ ......66 666..... */
-		/* ........ ........ ........ ........ ...77777 */
-		dst[4] = buf[6] << 5 | buf[7];
-
-		dst += 5;
-		dst_sz -= 5;
-	}
-	/* Not ending on a eight byte boundary? */
-	if (i > 0 && i < 8) {
-
-		/* Enough space available at the destination? */
-		if (dst_sz < (i + 1) / 2)
-			return -1;
-
-		switch (i) {
-		case 7: /* ........ ........ ........ ......66 666..... */
-			/* ........ ........ ........ .55555.. ........ */
-			/* ........ ........ ....4444 4....... ........ */
-			dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
-
-		case 5: /* ........ ........ ....4444 4....... ........ */
-			/* ........ .......3 3333.... ........ ........ */
-			dst[2] = buf[3] << 4 | buf[4] >> 1;
-
-		case 4: /* ........ .......3 3333.... ........ ........ */
-			/* ........ ..22222. ........ ........ ........ */
-			/* .....111 11...... ........ ........ ........ */
-			dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
-
-		case 2: /* .....111 11...... ........ ........ ........ */
-			/* 00000... ........ ........ ........ ........ */
-			dst[0] = buf[0] << 3 | buf[1] >> 2;
-
-			break;
-
-		default:
-			return -1;
-		}
-		dst += (i + 1) / 2;
-
-		if (check_padding) {
-			/* Check remaining padding characters */
-			if (ch != '=')
-				return -1;
-
-			/* One down, 8 - i - 1 more to come... */
-			for (i = 8 - i - 1; i > 0; i--) {
-
-				do {
-					if (src_sz == 0)
-						return -1;
-					ch = *src++;
-					src_sz--;
-
-				} while (isspace(ch));
-
-				if (ch != '=')
-					return -1;
-			}
-		}
-	}
-	return dst - start;
-}
-
-int
-ldns_b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz)
-{
-	return ldns_b32_pton_base(src, src_sz, dst, dst_sz, false, true);
-}
-
-int
-ldns_b32_pton_extended_hex(const char* src, size_t src_sz, 
-		uint8_t* dst, size_t dst_sz)
-{
-	return ldns_b32_pton_base(src, src_sz, dst, dst_sz, true, true);
-}
-
-#ifndef HAVE_B32_PTON
-
-int
-b32_pton(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz)
-{
-	return ldns_b32_pton_base(src, src_sz, dst, dst_sz, false, true);
-}
-
-int
-b32_pton_extended_hex(const char* src, size_t src_sz, 
-		uint8_t* dst, size_t dst_sz)
-{
-	return ldns_b32_pton_base(src, src_sz, dst, dst_sz, true, true);
-}
-
-#endif /* ! HAVE_B32_PTON */
-
diff --git a/src/ldns/wire2host.c b/src/ldns/wire2host.c
deleted file mode 100644
index e492215..0000000
--- a/src/ldns/wire2host.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * wire2host.c
- *
- * conversion routines from the wire to the host
- * format.
- * This will usually just a re-ordering of the
- * data (as we store it in network format)
- *
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2004-2006
- *
- * See the file LICENSE for the license
- */
-
-
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-/*#include <ldns/wire2host.h>*/
-
-#include <strings.h>
-#include <limits.h>
-
-
-
-/*
- * Set of macro's to deal with the dns message header as specified
- * in RFC1035 in portable way.
- *
- */
-
-/*
- *
- *                                    1  1  1  1  1  1
- *      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
- *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *    |                      ID                       |
- *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *    |QR|   Opcode  |AA|TC|RD|RA| Z|AD|CD|   RCODE   |
- *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *    |                    QDCOUNT                    |
- *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *    |                    ANCOUNT                    |
- *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *    |                    NSCOUNT                    |
- *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *    |                    ARCOUNT                    |
- *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- *
- */
-
-
-/* allocates memory to *dname! */
-ldns_status
-ldns_wire2dname(ldns_rdf **dname, const uint8_t *wire, size_t max, size_t *pos)
-{
-	uint8_t label_size;
-	uint16_t pointer_target;
-	uint8_t pointer_target_buf[2];
-	size_t dname_pos = 0;
-	size_t uncompressed_length = 0;
-	size_t compression_pos = 0;
-	uint8_t tmp_dname[LDNS_MAX_DOMAINLEN];
-	unsigned int pointer_count = 0;
-
-	if (pos == NULL) {
-		return LDNS_STATUS_WIRE_RDATA_ERR;
-	}
-	if (*pos >= max) {
-		return LDNS_STATUS_PACKET_OVERFLOW;
-	}
-	label_size = wire[*pos];
-	while (label_size > 0) {
-		/* compression */
-		while (label_size >= 192) {
-			if (compression_pos == 0) {
-				compression_pos = *pos + 2;
-			}
-
-			pointer_count++;
-
-			/* remove first two bits */
-			if (*pos + 2 > max) {
-				return LDNS_STATUS_PACKET_OVERFLOW;
-			}
-			pointer_target_buf[0] = wire[*pos] & 63;
-			pointer_target_buf[1] = wire[*pos + 1];
-			pointer_target = ldns_read_uint16(pointer_target_buf);
-
-			if (pointer_target == 0) {
-				return LDNS_STATUS_INVALID_POINTER;
-			} else if (pointer_target >= max) {
-				return LDNS_STATUS_INVALID_POINTER;
-			} else if (pointer_count > LDNS_MAX_POINTERS) {
-				return LDNS_STATUS_INVALID_POINTER;
-			}
-			*pos = pointer_target;
-			label_size = wire[*pos];
-		}
-		if(label_size == 0)
-			break; /* break from pointer to 0 byte */
-		if (label_size > LDNS_MAX_LABELLEN) {
-			return LDNS_STATUS_LABEL_OVERFLOW;
-		}
-		if (*pos + 1 + label_size > max) {
-			return LDNS_STATUS_LABEL_OVERFLOW;
-		}
-
-		/* check space for labelcount itself */
-		if (dname_pos + 1 > LDNS_MAX_DOMAINLEN) {
-			return LDNS_STATUS_DOMAINNAME_OVERFLOW;
-		}
-		tmp_dname[dname_pos] = label_size;
-		if (label_size > 0) {
-			dname_pos++;
-		}
-		*pos = *pos + 1;
-		if (dname_pos + label_size > LDNS_MAX_DOMAINLEN) {
-			return LDNS_STATUS_DOMAINNAME_OVERFLOW;
-		}
-		memcpy(&tmp_dname[dname_pos], &wire[*pos], label_size);
-		uncompressed_length += label_size + 1;
-		dname_pos += label_size;
-		*pos = *pos + label_size;
-
-		if (*pos < max) {
-			label_size = wire[*pos];
-		}
-	}
-
-	if (compression_pos > 0) {
-		*pos = compression_pos;
-	} else {
-		*pos = *pos + 1;
-	}
-
-	if (dname_pos >= LDNS_MAX_DOMAINLEN) {
-		return LDNS_STATUS_DOMAINNAME_OVERFLOW;
-	}
-
-	tmp_dname[dname_pos] = 0;
-	dname_pos++;
-
-	*dname = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
-			(uint16_t) dname_pos, tmp_dname);
-	if (!*dname) {
-		return LDNS_STATUS_MEM_ERR;
-	}
-	return LDNS_STATUS_OK;
-}
-
-/* maybe make this a goto error so data can be freed or something/ */
-#define LDNS_STATUS_CHECK_RETURN(st) {if (st != LDNS_STATUS_OK) { return st; }}
-#define LDNS_STATUS_CHECK_GOTO(st, label) {if (st != LDNS_STATUS_OK) { /*printf("STG %s:%d: status code %d\n", __FILE__, __LINE__, st);*/  goto label; }}
-
-ldns_status
-ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos)
-{
-	size_t end;
-	size_t cur_rdf_length;
-	uint8_t rdf_index;
-	uint8_t *data;
-	uint16_t rd_length;
-	ldns_rdf *cur_rdf = NULL;
-	ldns_rdf_type cur_rdf_type;
-	const ldns_rr_descriptor *descriptor;
-	ldns_status status;
-
-	assert(rr != NULL);
-
-	descriptor = ldns_rr_descript(ldns_rr_get_type(rr));
-
-	if (*pos + 2 > max) {
-		return LDNS_STATUS_PACKET_OVERFLOW;
-	}
-
-	rd_length = ldns_read_uint16(&wire[*pos]);
-	*pos = *pos + 2;
-
-	if (*pos + rd_length > max) {
-		return LDNS_STATUS_PACKET_OVERFLOW;
-	}
-
-	end = *pos + (size_t) rd_length;
-
-	rdf_index = 0;
-	while (*pos < end &&
-			rdf_index < ldns_rr_descriptor_maximum(descriptor)) {
-
-		cur_rdf_length = 0;
-
-		cur_rdf_type = ldns_rr_descriptor_field_type(
-				descriptor, rdf_index);
-
-		/* handle special cases immediately, set length
-		   for fixed length rdata and do them below */
-		switch (cur_rdf_type) {
-		case LDNS_RDF_TYPE_DNAME:
-			status = ldns_wire2dname(&cur_rdf, wire, max, pos);
-			LDNS_STATUS_CHECK_RETURN(status);
-			break;
-		case LDNS_RDF_TYPE_CLASS:
-		case LDNS_RDF_TYPE_ALG:
-		case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
-		case LDNS_RDF_TYPE_SELECTOR:
-		case LDNS_RDF_TYPE_MATCHING_TYPE:
-		case LDNS_RDF_TYPE_INT8:
-			cur_rdf_length = LDNS_RDF_SIZE_BYTE;
-			break;
-		case LDNS_RDF_TYPE_TYPE:
-		case LDNS_RDF_TYPE_INT16:
-		case LDNS_RDF_TYPE_CERT_ALG:
-			cur_rdf_length = LDNS_RDF_SIZE_WORD;
-			break;
-		case LDNS_RDF_TYPE_TIME:
-		case LDNS_RDF_TYPE_INT32:
-		case LDNS_RDF_TYPE_A:
-		case LDNS_RDF_TYPE_PERIOD:
-			cur_rdf_length = LDNS_RDF_SIZE_DOUBLEWORD;
-			break;
-		case LDNS_RDF_TYPE_TSIGTIME:
-		case LDNS_RDF_TYPE_EUI48:
-			cur_rdf_length = LDNS_RDF_SIZE_6BYTES;
-			break;
-		case LDNS_RDF_TYPE_ILNP64:
-		case LDNS_RDF_TYPE_EUI64:
-			cur_rdf_length = LDNS_RDF_SIZE_8BYTES;
-			break;
-		case LDNS_RDF_TYPE_AAAA:
-			cur_rdf_length = LDNS_RDF_SIZE_16BYTES;
-			break;
-		case LDNS_RDF_TYPE_STR:
-		case LDNS_RDF_TYPE_NSEC3_SALT:
-		case LDNS_RDF_TYPE_TAG:
-			/* len is stored in first byte
-			 * it should be in the rdf too, so just
-			 * copy len+1 from this position
-			 */
-			cur_rdf_length = ((size_t) wire[*pos]) + 1;
-			break;
-
-		case LDNS_RDF_TYPE_INT16_DATA:
-			if (*pos + 2 > end) {
-				return LDNS_STATUS_PACKET_OVERFLOW;
-			}
-			cur_rdf_length =
-				(size_t) ldns_read_uint16(&wire[*pos]) + 2;
-			break;
-		case LDNS_RDF_TYPE_HIP:
-			if (*pos + 4 > end) {
-				return LDNS_STATUS_PACKET_OVERFLOW;
-			}
-			cur_rdf_length =
-				(size_t) wire[*pos] + 
-				(size_t) ldns_read_uint16(&wire[*pos + 2]) + 4;
-			break;
-		case LDNS_RDF_TYPE_B32_EXT:
-		case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
-			/* length is stored in first byte */
-			cur_rdf_length = ((size_t) wire[*pos]) + 1;
-			break;
-		case LDNS_RDF_TYPE_APL:
-		case LDNS_RDF_TYPE_B64:
-		case LDNS_RDF_TYPE_HEX:
-		case LDNS_RDF_TYPE_NSEC:
-		case LDNS_RDF_TYPE_UNKNOWN:
-		case LDNS_RDF_TYPE_SERVICE:
-		case LDNS_RDF_TYPE_LOC:
-		case LDNS_RDF_TYPE_WKS:
-		case LDNS_RDF_TYPE_NSAP:
-		case LDNS_RDF_TYPE_ATMA:
-		case LDNS_RDF_TYPE_IPSECKEY:
-		case LDNS_RDF_TYPE_LONG_STR:
-		case LDNS_RDF_TYPE_NONE:
-			/*
-			 * Read to end of rr rdata
-			 */
-			cur_rdf_length = end - *pos;
-			break;
-		}
-
-		/* fixed length rdata */
-		if (cur_rdf_length > 0) {
-			if (cur_rdf_length + *pos > end) {
-				return LDNS_STATUS_PACKET_OVERFLOW;
-			}
-			data = LDNS_XMALLOC(uint8_t, rd_length);
-			if (!data) {
-				return LDNS_STATUS_MEM_ERR;
-			}
-			memcpy(data, &wire[*pos], cur_rdf_length);
-
-			cur_rdf = ldns_rdf_new(cur_rdf_type,
-					cur_rdf_length, data);
-			*pos = *pos + cur_rdf_length;
-		}
-
-		if (cur_rdf) {
-			ldns_rr_push_rdf(rr, cur_rdf);
-			cur_rdf = NULL;
-		}
-
-		rdf_index++;
-
-	} /* while (rdf_index < ldns_rr_descriptor_maximum(descriptor)) */
-
-
-	return LDNS_STATUS_OK;
-}
-
-
-/* TODO:
-         can *pos be incremented at READ_INT? or maybe use something like
-         RR_CLASS(wire)?
-	 uhhm Jelte??
-*/
-ldns_status
-ldns_wire2rr(ldns_rr **rr_p, const uint8_t *wire, size_t max,
-             size_t *pos, ldns_pkt_section section)
-{
-	ldns_rdf *owner = NULL;
-	ldns_rr *rr = ldns_rr_new();
-	ldns_status status;
-
-	status = ldns_wire2dname(&owner, wire, max, pos);
-	LDNS_STATUS_CHECK_GOTO(status, status_error);
-
-	ldns_rr_set_owner(rr, owner);
-
-	if (*pos + 4 > max) {
-		status = LDNS_STATUS_PACKET_OVERFLOW;
-		goto status_error;
-	}
-
-	ldns_rr_set_type(rr, ldns_read_uint16(&wire[*pos]));
-	*pos = *pos + 2;
-
-	ldns_rr_set_class(rr, ldns_read_uint16(&wire[*pos]));
-	*pos = *pos + 2;
-
-	if (section != LDNS_SECTION_QUESTION) {
-		if (*pos + 4 > max) {
-			status = LDNS_STATUS_PACKET_OVERFLOW;
-			goto status_error;
-		}
-		ldns_rr_set_ttl(rr, ldns_read_uint32(&wire[*pos]));
-
-		*pos = *pos + 4;
-		status = ldns_wire2rdf(rr, wire, max, pos);
-
-		LDNS_STATUS_CHECK_GOTO(status, status_error);
-        ldns_rr_set_question(rr, false);
-	} else {
-        ldns_rr_set_question(rr, true);
-    }
-
-	*rr_p = rr;
-	return LDNS_STATUS_OK;
-
-status_error:
-	ldns_rr_free(rr);
-	return status;
-}
-
-static ldns_status
-ldns_wire2pkt_hdr(ldns_pkt *packet, const uint8_t *wire, size_t max, size_t *pos)
-{
-	if (*pos + LDNS_HEADER_SIZE > max) {
-		return LDNS_STATUS_WIRE_INCOMPLETE_HEADER;
-	} else {
-		ldns_pkt_set_id(packet, LDNS_ID_WIRE(wire));
-		ldns_pkt_set_qr(packet, LDNS_QR_WIRE(wire));
-		ldns_pkt_set_opcode(packet, LDNS_OPCODE_WIRE(wire));
-		ldns_pkt_set_aa(packet, LDNS_AA_WIRE(wire));
-		ldns_pkt_set_tc(packet, LDNS_TC_WIRE(wire));
-		ldns_pkt_set_rd(packet, LDNS_RD_WIRE(wire));
-		ldns_pkt_set_ra(packet, LDNS_RA_WIRE(wire));
-		ldns_pkt_set_ad(packet, LDNS_AD_WIRE(wire));
-		ldns_pkt_set_cd(packet, LDNS_CD_WIRE(wire));
-		ldns_pkt_set_rcode(packet, LDNS_RCODE_WIRE(wire));
-
-		ldns_pkt_set_qdcount(packet, LDNS_QDCOUNT(wire));
-		ldns_pkt_set_ancount(packet, LDNS_ANCOUNT(wire));
-		ldns_pkt_set_nscount(packet, LDNS_NSCOUNT(wire));
-		ldns_pkt_set_arcount(packet, LDNS_ARCOUNT(wire));
-
-		*pos += LDNS_HEADER_SIZE;
-
-		return LDNS_STATUS_OK;
-	}
-}
-
-ldns_status
-ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer)
-{
-	/* lazy */
-	return ldns_wire2pkt(packet, ldns_buffer_begin(buffer),
-				ldns_buffer_limit(buffer));
-
-}
-
-ldns_status
-ldns_wire2pkt(ldns_pkt **packet_p, const uint8_t *wire, size_t max)
-{
-	size_t pos = 0;
-	uint16_t i;
-	ldns_rr *rr;
-	ldns_pkt *packet = ldns_pkt_new();
-	ldns_status status = LDNS_STATUS_OK;
-	uint8_t have_edns = 0;
-
-	uint8_t data[4];
-
-	status = ldns_wire2pkt_hdr(packet, wire, max, &pos);
-	LDNS_STATUS_CHECK_GOTO(status, status_error);
-
-	for (i = 0; i < ldns_pkt_qdcount(packet); i++) {
-
-		status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_QUESTION);
-		if (status == LDNS_STATUS_PACKET_OVERFLOW) {
-			status = LDNS_STATUS_WIRE_INCOMPLETE_QUESTION;
-		}
-		LDNS_STATUS_CHECK_GOTO(status, status_error);
-		if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
-			ldns_pkt_free(packet);
-			return LDNS_STATUS_INTERNAL_ERR;
-		}
-	}
-	for (i = 0; i < ldns_pkt_ancount(packet); i++) {
-		status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_ANSWER);
-		if (status == LDNS_STATUS_PACKET_OVERFLOW) {
-			status = LDNS_STATUS_WIRE_INCOMPLETE_ANSWER;
-		}
-		LDNS_STATUS_CHECK_GOTO(status, status_error);
-		if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
-			ldns_pkt_free(packet);
-			return LDNS_STATUS_INTERNAL_ERR;
-		}
-	}
-	for (i = 0; i < ldns_pkt_nscount(packet); i++) {
-		status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_AUTHORITY);
-		if (status == LDNS_STATUS_PACKET_OVERFLOW) {
-			status = LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY;
-		}
-		LDNS_STATUS_CHECK_GOTO(status, status_error);
-		if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
-			ldns_pkt_free(packet);
-			return LDNS_STATUS_INTERNAL_ERR;
-		}
-	}
-	for (i = 0; i < ldns_pkt_arcount(packet); i++) {
-		status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_ADDITIONAL);
-		if (status == LDNS_STATUS_PACKET_OVERFLOW) {
-			status = LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL;
-		}
-		LDNS_STATUS_CHECK_GOTO(status, status_error);
-
-		if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_OPT) {
-			ldns_pkt_set_edns_udp_size(packet, ldns_rr_get_class(rr));
-			ldns_write_uint32(data, ldns_rr_ttl(rr));
-			ldns_pkt_set_edns_extended_rcode(packet, data[0]);
-			ldns_pkt_set_edns_version(packet, data[1]);
-			ldns_pkt_set_edns_z(packet, ldns_read_uint16(&data[2]));
-			/* edns might not have rdfs */
-			if (ldns_rr_rdf(rr, 0)) {
-				ldns_pkt_set_edns_data(packet, ldns_rdf_clone(ldns_rr_rdf(rr, 0)));
-			}
-			ldns_rr_free(rr);
-			have_edns += 1;
-		} else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_TSIG) {
-			ldns_pkt_set_tsig(packet, rr);
-			ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) - 1);
-		} else if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
-			ldns_pkt_free(packet);
-			return LDNS_STATUS_INTERNAL_ERR;
-		}
-	}
-	ldns_pkt_set_size(packet, max);
-	if(have_edns)
-		ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet)
-                        - have_edns);
-        packet->_edns_present = have_edns;
-
-	*packet_p = packet;
-	return status;
-
-status_error:
-	ldns_pkt_free(packet);
-	return status;
-}
diff --git a/src/ldns/zone.c b/src/ldns/zone.c
deleted file mode 100644
index d97a81e..0000000
--- a/src/ldns/zone.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* zone.c
- *
- * Functions for ldns_zone structure
- * a Net::DNS like library for C
- *
- * (c) NLnet Labs, 2005-2006
- * See the file LICENSE for the license
- */
-#include <ldns/config.h>
-
-#include <ldns/ldns.h>
-
-#include <strings.h>
-#include <limits.h>
-
-ldns_rr *
-ldns_zone_soa(const ldns_zone *z)
-{
-        return z->_soa;
-}
-
-size_t
-ldns_zone_rr_count(const ldns_zone *z)
-{
-	return ldns_rr_list_rr_count(z->_rrs);
-}
-
-void
-ldns_zone_set_soa(ldns_zone *z, ldns_rr *soa)
-{
-	z->_soa = soa;
-}
-
-ldns_rr_list *
-ldns_zone_rrs(const ldns_zone *z)
-{
-	return z->_rrs;
-}
-
-void
-ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist)
-{
-	z->_rrs = rrlist;
-}
-
-bool
-ldns_zone_push_rr_list(ldns_zone *z, ldns_rr_list *list)
-{
-	return ldns_rr_list_cat(ldns_zone_rrs(z), list);
-
-}
-
-bool
-ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
-{
-	return ldns_rr_list_push_rr( ldns_zone_rrs(z), rr);
-}
-
-
-/*
- * Get the list of glue records in a zone
- * XXX: there should be a way for this to return error, other than NULL, 
- *      since NULL is a valid return
- */
-ldns_rr_list *
-ldns_zone_glue_rr_list(const ldns_zone *z)
-{
-	/* when do we find glue? It means we find an IP address
-	 * (AAAA/A) for a nameserver listed in the zone
-	 *
-	 * Alg used here:
-	 * first find all the zonecuts (NS records)
-	 * find all the AAAA or A records (can be done it the 
-	 * above loop).
-	 *
-	 * Check if the aaaa/a list are subdomains under the
-	 * NS domains.
-	 * If yes -> glue, if no -> not glue
-	 */
-
-	ldns_rr_list *zone_cuts;
-	ldns_rr_list *addr;
-	ldns_rr_list *glue;
-	ldns_rr *r, *ns, *a;
-	ldns_rdf *dname_a, *ns_owner;
-	size_t i,j;
-
-	zone_cuts = NULL;
-	addr = NULL;
-	glue = NULL;
-
-	/* we cannot determine glue in a 'zone' without a SOA */
-	if (!ldns_zone_soa(z)) {
-		return NULL;
-	}
-
-	zone_cuts = ldns_rr_list_new();
-	if (!zone_cuts) goto memory_error;
-	addr = ldns_rr_list_new();
-	if (!addr) goto memory_error;
-	glue = ldns_rr_list_new();
-	if (!glue) goto memory_error;
-
-	for(i = 0; i < ldns_zone_rr_count(z); i++) {
-		r = ldns_rr_list_rr(ldns_zone_rrs(z), i);
-		if (ldns_rr_get_type(r) == LDNS_RR_TYPE_A ||
-				ldns_rr_get_type(r) == LDNS_RR_TYPE_AAAA) {
-			/* possibly glue */
-			if (!ldns_rr_list_push_rr(addr, r)) goto memory_error;
-			continue;
-		}
-		if (ldns_rr_get_type(r) == LDNS_RR_TYPE_NS) {
-			/* multiple zones will end up here -
-			 * for now; not a problem
-			 */
-			/* don't add NS records for the current zone itself */
-			if (ldns_rdf_compare(ldns_rr_owner(r), 
-						ldns_rr_owner(ldns_zone_soa(z))) != 0) {
-				if (!ldns_rr_list_push_rr(zone_cuts, r)) goto memory_error;
-			}
-			continue;
-		}
-	}
-
-	/* will sorting make it quicker ?? */
-	for(i = 0; i < ldns_rr_list_rr_count(zone_cuts); i++) {
-		ns = ldns_rr_list_rr(zone_cuts, i);
-		ns_owner = ldns_rr_owner(ns);
-
-		for(j = 0; j < ldns_rr_list_rr_count(addr); j++) {
-			a = ldns_rr_list_rr(addr, j);
-			dname_a = ldns_rr_owner(a);
-
-			if (ldns_dname_is_subdomain(dname_a, ns_owner) ||
-				ldns_dname_compare(dname_a, ns_owner) == 0) {
-				/* GLUE! */
-				if (!ldns_rr_list_push_rr(glue, a)) goto memory_error;
-			}
-		}
-	}
-	
-	ldns_rr_list_free(addr);
-	ldns_rr_list_free(zone_cuts);
-
-	if (ldns_rr_list_rr_count(glue) == 0) {
-		ldns_rr_list_free(glue);
-		return NULL;
-	} else {
-		return glue;
-	}
-
-memory_error:
-	if (zone_cuts) {
-		LDNS_FREE(zone_cuts);
-	}
-	if (addr) {
-		ldns_rr_list_free(addr);
-	}
-	if (glue) {
-		ldns_rr_list_free(glue);
-	}
-	return NULL;
-}
-
-ldns_zone *
-ldns_zone_new(void)
-{
-	ldns_zone *z;
-
-	z = LDNS_MALLOC(ldns_zone);
-	if (!z) {
-		return NULL;
-	}
-
-	z->_rrs = ldns_rr_list_new();
-	if (!z->_rrs) {
-		LDNS_FREE(z);
-		return NULL;
-	}
-	ldns_zone_set_soa(z, NULL);
-	return z;
-}
-
-/* we regocnize:
- * $TTL, $ORIGIN
- */
-ldns_status
-ldns_zone_new_frm_fp(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c)
-{
-	return ldns_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL);
-}
-
-/* XXX: class is never used */
-ldns_status
-ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, 
-        ldns_rr_class ATTR_UNUSED(c), int *line_nr)
-{
-	ldns_zone *newzone;
-	ldns_rr *rr;
-	uint32_t my_ttl;
-	ldns_rdf *my_origin;
-	ldns_rdf *my_prev;
-	bool soa_seen = false; 	/* 2 soa are an error */
-	ldns_status s;
-	ldns_status ret;
-
-	/* most cases of error are memory problems */
-	ret = LDNS_STATUS_MEM_ERR;
-
-	newzone = NULL;
-	my_origin = NULL;
-	my_prev = NULL;
-
-	my_ttl    = ttl;
-	
-	if (origin) {
-		my_origin = ldns_rdf_clone(origin);
-		if (!my_origin) goto error;
-		/* also set the prev */
-		my_prev   = ldns_rdf_clone(origin);
-		if (!my_prev) goto error;
-	}
-
-	newzone = ldns_zone_new();
-	if (!newzone) goto error;
-
-	while(!feof(fp)) {
-		s = ldns_rr_new_frm_fp_l(&rr, fp, &my_ttl, &my_origin, &my_prev, line_nr);
-		switch (s) {
-		case LDNS_STATUS_OK:
-			if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
-				if (soa_seen) {
-					/* second SOA 
-					 * just skip, maybe we want to say
-					 * something??? */
-					ldns_rr_free(rr);
-					continue;
-				}
-				soa_seen = true;
-				ldns_zone_set_soa(newzone, rr);
-				/* set origin to soa if not specified */
-				if (!my_origin) {
-					my_origin = ldns_rdf_clone(ldns_rr_owner(rr));
-				}
-				continue;
-			}
-			
-			/* a normal RR - as sofar the DNS is normal */
-			if (!ldns_zone_push_rr(newzone, rr)) goto error;
-
-		case LDNS_STATUS_SYNTAX_EMPTY:
-			/* empty line was seen */
-		case LDNS_STATUS_SYNTAX_TTL:
-			/* the function set the ttl */
-			break;
-		case LDNS_STATUS_SYNTAX_ORIGIN:
-			/* the function set the origin */
-			break;
-		case LDNS_STATUS_SYNTAX_INCLUDE:
-			ret = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL;
-			break;
-		default:
-			ret = s;
-			goto error;
-		}
-	}
-
-	if (my_origin) {
-		ldns_rdf_deep_free(my_origin);
-	}
-	if (my_prev) {
-		ldns_rdf_deep_free(my_prev);
-	}
-	if (z) {
-		*z = newzone;
-	} else {
-		ldns_zone_free(newzone);
-	}
-
-	return LDNS_STATUS_OK;
-
-error:
-	if (my_origin) {
-		ldns_rdf_deep_free(my_origin);
-	}
-	if (my_prev) {
-		ldns_rdf_deep_free(my_prev);
-	}
-	if (newzone) {
-		ldns_zone_free(newzone);
-	}
-	return ret;
-}
-
-void
-ldns_zone_sort(ldns_zone *zone)
-{
-	ldns_rr_list *zrr;
-	assert(zone != NULL);
-
-	zrr = ldns_zone_rrs(zone);
-	ldns_rr_list_sort(zrr);
-}
-
-void
-ldns_zone_free(ldns_zone *zone) 
-{
-	ldns_rr_list_free(zone->_rrs);
-	LDNS_FREE(zone);
-}
-
-void
-ldns_zone_deep_free(ldns_zone *zone) 
-{
-	ldns_rr_free(zone->_soa);
-	ldns_rr_list_deep_free(zone->_rrs);
-	LDNS_FREE(zone);
-}
