From b2c7071c57b2dd6ece8fd190506399a3cd79c7bd Mon Sep 17 00:00:00 2001
From: Daniel Salzman <daniel.salzman@nic.cz>
Date: Mon, 18 Feb 2013 16:28:46 +0100
Subject: [PATCH] Improve RR descriptors

- Add missing descriptors.
- Extend descriptor structure with type name.
- Add conversion functions num<->str for types and classes.

refs @2138

Conflicts:

	src/common/descriptor_new.c
	src/common/descriptor_new.h
---
 Knot.files                          |   2 +
 src/Makefile.am                     |   6 +-
 src/common/descriptor_new.c         | 261 +++++++++++++++++++++++-----
 src/common/descriptor_new.h         | 123 ++++++++++++-
 src/libknot/packet/packet.c         |   1 -
 src/libknot/util/descriptor.c       |  22 ++-
 src/libknot/util/descriptor.h       |  18 +-
 src/tests/common/descriptor_tests.c | 234 +++++++++++++++++++++++++
 src/tests/common/descriptor_tests.h |  25 +++
 src/tests/unittests_main.c          |   2 +
 10 files changed, 617 insertions(+), 77 deletions(-)
 create mode 100644 src/tests/common/descriptor_tests.c
 create mode 100644 src/tests/common/descriptor_tests.h

diff --git a/Knot.files b/Knot.files
index 850c85f3b..aee6f9255 100644
--- a/Knot.files
+++ b/Knot.files
@@ -191,6 +191,8 @@ src/tests/common/base64_tests.c
 src/tests/common/base64_tests.h
 src/tests/common/base32hex_tests.c
 src/tests/common/base32hex_tests.h
+src/tests/common/descriptor_tests.c
+src/tests/common/descriptor_tests.h
 src/tests/knot/dthreads_tests.c
 src/tests/knot/dthreads_tests.h
 src/tests/knot/conf_tests.c
diff --git a/src/Makefile.am b/src/Makefile.am
index e1f0bbf12..9223cd285 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -113,14 +113,16 @@ unittests_SOURCES =				\
 	tests/common/base32hex_tests.h		\
 	tests/common/base64_tests.c		\
 	tests/common/base64_tests.h		\
+	tests/common/descriptor_tests.h		\
+	tests/common/descriptor_tests.c		\
 	tests/common/events_tests.c		\
 	tests/common/events_tests.h		\
+	tests/common/fdset_tests.c		\
+	tests/common/fdset_tests.h		\
 	tests/common/skiplist_tests.c		\
 	tests/common/skiplist_tests.h		\
 	tests/common/slab_tests.c		\
 	tests/common/slab_tests.h		\
-	tests/common/fdset_tests.c		\
-	tests/common/fdset_tests.h		\
 	tests/knot/conf_tests.c			\
 	tests/knot/conf_tests.h			\
 	tests/knot/dthreads_tests.c		\
diff --git a/src/common/descriptor_new.c b/src/common/descriptor_new.c
index be8b3c427..07b3779df 100644
--- a/src/common/descriptor_new.c
+++ b/src/common/descriptor_new.c
@@ -15,93 +15,264 @@
  */
 
 #include "common/descriptor_new.h"
+#include "libknot/util/utils.h"		// knot_lookup_table_t
+
+#include <stdio.h>			// snprintf
+#include <stdlib.h>			// strtoul
+
+/*! 
+ * \brief The last RR type number in the descriptors table.
+ */
+const int KNOT_RRTYPE_LAST = KNOT_RRTYPE_ANY;
+
+/*!
+ * \brief Table with DNS classes.
+ */
+static knot_lookup_table_t dns_classes[] = {
+	{ KNOT_CLASS_IN,   "IN" },
+	{ KNOT_CLASS_CH,   "CH" },
+	{ KNOT_CLASS_NONE, "NONE" },
+	{ KNOT_CLASS_ANY,  "ANY" },
+	{ 0, NULL }
+};
 
 /*!
  * \brief RR type descriptors.
  */
 static const rdata_descriptor_t rdata_descriptors[] = {
-	[0]			 = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
-	[KNOT_RRTYPE_A]          = { { 4, KNOT_RDATA_WF_END } },
+	[0]                      = { { KNOT_RDATA_WF_REMAINDER,
+	                               KNOT_RDATA_WF_END } },
+	[KNOT_RRTYPE_A]          = { { 4, KNOT_RDATA_WF_END }, "A" },
 	[KNOT_RRTYPE_NS]         = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "NS" },
 	[KNOT_RRTYPE_CNAME]      = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "CNAME" },
 	[KNOT_RRTYPE_SOA]        = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       20, KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_COMPRESSED_DNAME,
+	                               20, KNOT_RDATA_WF_END }, "SOA" },
 	[KNOT_RRTYPE_PTR]        = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "PTR" },
 	[KNOT_RRTYPE_HINFO]      = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "HINFO" },
 	[KNOT_RRTYPE_MINFO]      = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_COMPRESSED_DNAME,
+	                               KNOT_RDATA_WF_END }, "MINFO" },
 	[KNOT_RRTYPE_MX]         = { { 2, KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "MX" },
 	[KNOT_RRTYPE_TXT]        = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "TXT" },
 	[KNOT_RRTYPE_RP]         = { { KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_COMPRESSED_DNAME,
+	                               KNOT_RDATA_WF_END }, "RP" },
 	[KNOT_RRTYPE_AFSDB]      = { { 2, KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "AFSDB" },
 	[KNOT_RRTYPE_RT]         = { { 2, KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "RT" },
 	[KNOT_RRTYPE_KEY]        = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
-	[KNOT_RRTYPE_AAAA]       = { { 16, KNOT_RDATA_WF_END } },
-	[KNOT_RRTYPE_LOC]        = { { 16, KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "KEY" },
+	[KNOT_RRTYPE_AAAA]       = { { 16, KNOT_RDATA_WF_END }, "AAAA" },
+	[KNOT_RRTYPE_LOC]        = { { 16, KNOT_RDATA_WF_END }, "LOC" },
 	[KNOT_RRTYPE_SRV]        = { { 6, KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "SRV" },
 	[KNOT_RRTYPE_NAPTR]      = { { KNOT_RDATA_WF_NAPTR_HEADER,
-				       KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
+	                               KNOT_RDATA_WF_END }, "NAPTR" },
 	[KNOT_RRTYPE_KX]         = { { 2, KNOT_RDATA_WF_COMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "KX" },
 	[KNOT_RRTYPE_CERT]       = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "CERT" },
 	[KNOT_RRTYPE_DNAME]      = { { KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "DNAME" },
 	[KNOT_RRTYPE_OPT]        = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "OPT" },
 	[KNOT_RRTYPE_APL]        = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "APL" },
 	[KNOT_RRTYPE_DS]         = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "DS" },
 	[KNOT_RRTYPE_SSHFP]      = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "SSHFP" },
 	[KNOT_RRTYPE_IPSECKEY]   = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "IPSECKEY" },
 	[KNOT_RRTYPE_RRSIG]      = { { 18, KNOT_RDATA_WF_LITERAL_DNAME,
-				       KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_REMAINDER,
+	                               KNOT_RDATA_WF_END }, "RRSIG" },
 	[KNOT_RRTYPE_NSEC]       = { { KNOT_RDATA_WF_LITERAL_DNAME,
-				       KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_REMAINDER,
+	                               KNOT_RDATA_WF_END }, "NSEC" },
 	[KNOT_RRTYPE_DNSKEY]     = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "DNSKEY" },
 	[KNOT_RRTYPE_DHCID]      = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "DHCID" },
 	[KNOT_RRTYPE_NSEC3]      = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "NSEC3" },
 	[KNOT_RRTYPE_NSEC3PARAM] = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "NSEC3PARAM" },
 	[KNOT_RRTYPE_TLSA]       = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "TLSA" },
 	[KNOT_RRTYPE_SPF]        = { { KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
-	[KNOT_RRTYPE_TSIG]       = { { KNOT_RDATA_WF_UNCOMPRESSED_DNAME,
-				       KNOT_RDATA_WF_REMAINDER,
-				       KNOT_RDATA_WF_END } },
+	                               KNOT_RDATA_WF_END }, "SPF" },
+	[KNOT_RRTYPE_TKEY]       = { { KNOT_RDATA_WF_REMAINDER,
+	                               KNOT_RDATA_WF_END }, "TKEY" },
+	[KNOT_RRTYPE_TSIG]       = { { KNOT_RDATA_WF_REMAINDER,
+	                               KNOT_RDATA_WF_END }, "TSIG" },
+	[KNOT_RRTYPE_IXFR]       = { { KNOT_RDATA_WF_REMAINDER,
+	                               KNOT_RDATA_WF_END }, "IXFR" },
+	[KNOT_RRTYPE_AXFR]       = { { KNOT_RDATA_WF_REMAINDER,
+	                               KNOT_RDATA_WF_END }, "AXFR" },
+	[KNOT_RRTYPE_ANY]        = { { KNOT_RDATA_WF_REMAINDER,
+	                               KNOT_RDATA_WF_END }, "ANY" },
 };
 
 const rdata_descriptor_t *get_rdata_descriptor(const uint16_t type)
 {
-	if (type <= KNOT_RRTYPE_TSIG) {
+	if (type <= KNOT_RRTYPE_ANY && rdata_descriptors[type].type_name != 0) {
 		return &rdata_descriptors[type];
 	} else {
 		return &rdata_descriptors[0];
 	}
 }
 
+int knot_rrtype_to_string(const uint16_t rrtype,
+                          char           *out,
+                          const size_t   out_len)
+{
+	int ret;
+
+	const rdata_descriptor_t *descr = get_rdata_descriptor(rrtype);
+
+	if (descr->type_name != 0) {
+		ret = snprintf(out, out_len, "%s", descr->type_name);
+	} else {
+		ret = snprintf(out, out_len, "TYPE%u", rrtype);
+	}
+
+	if (ret <= 0 || ret >= out_len) {
+		return -1;
+	} else {
+		return ret;
+	}
+}
+
+int knot_rrtype_from_string(const char *name, uint16_t *num)
+{
+	char *end;
+	unsigned i;
+	unsigned long n;
+
+	// Try to find name in descriptors table.
+	for (i = 0; i <= KNOT_RRTYPE_LAST; i++) {
+		if (rdata_descriptors[i].type_name != 0 &&
+		    strcasecmp(rdata_descriptors[i].type_name, name) == 0) {
+			*num = i;
+			return 0;
+		}
+	}
+
+	// Type name must begin with TYPE.
+	if (strncasecmp(name, "TYPE", 4) != 0) {
+		return -1;
+	} else {
+		name += 4;
+	}
+
+	// The rest must be a number.
+	n = strtoul(name, &end, 10);
+	if (end == name || *end != '\0' || n > UINT16_MAX) {
+		return -1;
+	}
+
+	*num = n;
+	return 0;
+}
+
+int knot_rrclass_to_string(const uint16_t rrclass,
+                           char           *out,
+                           const size_t   out_len)
+{
+	int ret;
+
+	knot_lookup_table_t *entry = knot_lookup_by_id(dns_classes, rrclass);
+
+	if (entry != NULL) {
+		ret = snprintf(out, out_len, "%s", entry->name);
+	} else {
+		ret = snprintf(out, out_len, "CLASS%u", rrclass);
+	}
+
+	if (ret <= 0 || ret >= out_len) {
+		return -1;
+	} else {
+		return ret;
+	}
+}
+
+int knot_rrclass_from_string(const char *name, uint16_t *num)
+{
+	char *end;
+	unsigned long n;
+
+	// Try to find name in lookup table.
+	knot_lookup_table_t *entry = knot_lookup_by_name(dns_classes, name);
+
+	if (entry != NULL) {
+		*num = entry->id;
+		return 0;
+	}
+
+	// Class name must begin with CLASS.
+	if (strncasecmp(name, "CLASS", 5) != 0) {
+		return -1;
+	} else {
+		name += 5;
+	}
+
+	// The rest must be a number.
+	n = strtoul(name, &end, 10);
+	if (end == name || *end != '\0' || n > UINT16_MAX) {
+		return -1;
+	}
+
+	*num = n;
+	return 0;
+}
+
+int descriptor_item_is_dname(const int item)
+{
+	return item == KNOT_RDATA_WF_LITERAL_DNAME ||
+	       item == KNOT_RDATA_WF_COMPRESSED_DNAME ||
+	       item == KNOT_RDATA_WF_UNCOMPRESSED_DNAME;
+}
+
+int descriptor_item_is_compr_dname(const int item)
+{
+	return item == KNOT_RDATA_WF_COMPRESSED_DNAME;
+}
+
+int descriptor_item_is_fixed(const int item)
+{
+	if (item > 0) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+int descriptor_item_is_remainder(const int item)
+{
+	if (item == KNOT_RDATA_WF_REMAINDER) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+int knot_rrtype_is_metatype(const uint16_t type)
+{
+	return (type == KNOT_RRTYPE_OPT ||
+	        type == KNOT_RRTYPE_TKEY ||
+	        type == KNOT_RRTYPE_TSIG ||
+	        type == KNOT_RRTYPE_IXFR ||
+	        type == KNOT_RRTYPE_AXFR ||
+	        type == KNOT_RRTYPE_ANY);
+}
+
diff --git a/src/common/descriptor_new.h b/src/common/descriptor_new.h
index e6ec6dd48..4bf23f8f4 100644
--- a/src/common/descriptor_new.h
+++ b/src/common/descriptor_new.h
@@ -18,13 +18,15 @@
  *
  * \author Jan Kadlec <jan.kadlec@nic.cz>
  *
+ * \addtogroup common_lib
  * @{
  */
 
 #ifndef _KNOT_DESCRIPTOR_NEW_H_
 #define _KNOT_DESCRIPTOR_NEW_H_
 
-#include <stdint.h>
+#include <stdint.h>			// uint16_t
+#include <stdio.h>			// size_t
 
 #define KNOT_MAX_RDATA_BLOCKS	8
 
@@ -33,6 +35,7 @@
  */
 enum knot_rr_class {
 	KNOT_CLASS_IN   =   1,
+	KNOT_CLASS_CH   =   2,
 	KNOT_CLASS_NONE = 254,
 	KNOT_CLASS_ANY  = 255,
 };
@@ -70,7 +73,7 @@ enum knot_rr_type {
 
 	KNOT_RRTYPE_DNAME      =  39, /*!< Delegation name. */
 
-	KNOT_RRTYPE_OPT        =  41, /*!< Option for EDNS*/
+	KNOT_RRTYPE_OPT        =  41, /*!< METATYPE. Option for EDNS. */
 	KNOT_RRTYPE_APL        =  42, /*!< Address prefix list. */
 	KNOT_RRTYPE_DS         =  43, /*!< Delegation signer. */
 	KNOT_RRTYPE_SSHFP      =  44, /*!< SSH public key fingerprint. */
@@ -81,15 +84,16 @@ enum knot_rr_type {
 	KNOT_RRTYPE_DHCID      =  49, /*!< DHCP identifier. */
 	KNOT_RRTYPE_NSEC3      =  50, /*!< NSEC version 3. */
 	KNOT_RRTYPE_NSEC3PARAM =  51, /*!< NSEC3 parameters. */
-	KNOT_RRTYPE_TLSA       =  52, /*!< DANE. */
+	KNOT_RRTYPE_TLSA       =  52, /*!< DANE record. */
 
 	KNOT_RRTYPE_SPF        =  99, /*!< Sender policy framework. */
 
-	KNOT_RRTYPE_TSIG       = 250, /*!< Transaction signature. */
-	KNOT_RRTYPE_IXFR       = 251, /*!< Incremental zone transfer. */
-	KNOT_RRTYPE_AXFR       = 252, /*!< Authoritative zone transfer. */
+	KNOT_RRTYPE_TKEY       = 249, /*!< METATYPE. Transaction key. */
+	KNOT_RRTYPE_TSIG       = 250, /*!< METATYPE. Transaction signature. */
+	KNOT_RRTYPE_IXFR       = 251, /*!< QTYPE. Incremental zone transfer. */
+	KNOT_RRTYPE_AXFR       = 252, /*!< QTYPE. Authoritative zone transfer. */
 
-	KNOT_RRTYPE_ANY        = 255, /*!< Any record. */
+	KNOT_RRTYPE_ANY        = 255, /*!< QTYPE. Any record. */
 };
 
 /*!
@@ -114,7 +118,10 @@ enum knot_rdata_wireformat {
  * \brief Structure describing rdata.
  */
 typedef struct {
-	int block_types[KNOT_MAX_RDATA_BLOCKS];
+	/*!< Item types describing rdata. */
+	const int  block_types[KNOT_MAX_RDATA_BLOCKS];
+	/*!< RR type name. */
+	const char *type_name;
 } rdata_descriptor_t;
 
 /*!
@@ -127,6 +134,106 @@ typedef struct {
  */
 const rdata_descriptor_t *get_rdata_descriptor(const uint16_t type);
 
+/*!
+ * \brief Converts numeric type representation to mnemonic string.
+ *
+ * \param rrtype  Type RR type code to be converted.
+ * \param out     Output buffer.
+ * \param out_len Length of the output buffer.
+ *
+ * \return Length of output string.
+ * \return -1 if error.
+ */
+int knot_rrtype_to_string(const uint16_t rrtype,
+                          char           *out,
+                          const size_t   out_len);
+
+/*!
+ * \brief Converts mnemonic string representation of a type to numeric one.
+ *
+ * \param name Mnemonic string to be converted.
+ * \param num  Output variable.
+ *
+ * \return  0 if OK.
+ * \return -1 if error.
+ */
+int knot_rrtype_from_string(const char *name, uint16_t *num);
+
+/*!
+ * \brief Converts numeric class representation to the string one.
+ *
+ * \param rrclass Class code to be converted.
+ * \param out     Output buffer.
+ * \param out_len Length of the output buffer.
+ *
+ * \return Length of output string.
+ * \return -1 if error.
+ */
+int knot_rrclass_to_string(const uint16_t rrclass,
+                           char           *out,
+                           const size_t   out_len);
+
+/*!
+ * \brief Converts string representation of a class to numeric one.
+ *
+ * \param name Mnemonic string to be converted.
+ * \param num  Output variable.
+ *
+ * \return  0 if OK.
+ * \return -1 if error.
+ */
+int knot_rrclass_from_string(const char *name, uint16_t *num);
+
+/*!
+ * \brief Checks if given item is one of dname types.
+ *
+ * \param item Item value.
+ *
+ * \return 1 if YES.
+ * \return 0 if NO.
+ */
+int descriptor_item_is_dname(const int item);
+
+/*!
+ * \brief Checks if given item is compressible dname.
+ *
+ * \param item Item value.
+ *
+ * \return 1 if YES.
+ * \return 0 if NO.
+ */
+int descriptor_item_is_compr_dname(const int item);
+
+/*!
+ * \brief Checks if given item has fixed size.
+ *
+ * \param item Item value.
+ *
+ * \return 1 if YES.
+ * \return 0 if NO.
+ */
+int descriptor_item_is_fixed(const int item);
+
+/*!
+ * \brief Checks if given item is remainder.
+ *
+ * \param item Item value.
+ *
+ * \return 1 if YES.
+ * \return 0 if NO.
+ */
+int descriptor_item_is_remainder(const int item);
+
+/*!
+ * \brief Checks if given item is one of metatypes or qtypes.
+ *
+ * \param item Item value.
+ *
+ * \return 1 if YES.
+ * \return 0 if NO.
+ */
+int knot_rrtype_is_metatype(const uint16_t type);
+
 #endif // _KNOT_DESCRIPTOR_NEW_H_
 
 /*! @} */
diff --git a/src/libknot/packet/packet.c b/src/libknot/packet/packet.c
index ef11d16f0..7f4595f00 100644
--- a/src/libknot/packet/packet.c
+++ b/src/libknot/packet/packet.c
@@ -282,7 +282,6 @@ static int knot_packet_parse_question(const uint8_t *wire, size_t *pos,
 	dbg_packet_verb("Parsing dname starting on position %zu and "
 	                      "%zu bytes long.\n", *pos, i - *pos + 1);
 	dbg_packet_verb("Alloc: %d\n", alloc);
-	size_t bp = *pos;
 	if (alloc) {
 		question->qname = knot_dname_parse_from_wire(wire, pos,
 		                                             i + 1,
diff --git a/src/libknot/util/descriptor.c b/src/libknot/util/descriptor.c
index dcfcf32d6..199fa9685 100644
--- a/src/libknot/util/descriptor.c
+++ b/src/libknot/util/descriptor.c
@@ -60,13 +60,13 @@ enum desclen { KNOT_RRTYPE_DESCRIPTORS_LENGTH = 32770 }; // used to be 101
 /*!
  * \brief Table for linking RR class constants to their textual representation.
  */
-static knot_lookup_table_t dns_rrclasses[] = {
-	{ KNOT_CLASS_IN, "IN" },	/* the Internet */
-	{ KNOT_CLASS_CS, "CS" },	/* the CSNET class (Obsolete) */
-	{ KNOT_CLASS_CH, "CH" },	/* the CHAOS class */
-	{ KNOT_CLASS_HS, "HS" },	/* Hesiod */
+/*static knot_lookup_table_t dns_rrclasses[] = {
+	{ KNOT_CLASS_IN, "IN" },
+	{ KNOT_CLASS_CS, "CS" },
+	{ KNOT_CLASS_CH, "CH" },
+	{ KNOT_CLASS_HS, "HS" },
 	{ 0, NULL }
-};
+};*/
 
 /*! \brief DS digest lengths. */
 enum knot_ds_algorithm_len
@@ -462,7 +462,7 @@ knot_rrtype_descriptor_t *knot_rrtype_descriptor_by_name(const char *name)
 
 	return NULL;
 }
-
+/*
 int knot_rrtype_to_string(const uint16_t rrtype,
                           char           *out,
                           const size_t   out_len)
@@ -509,7 +509,6 @@ int knot_rrtype_from_string(const char *name, uint16_t *num)
 		return -1;
 	}
 
-	/* The rest from the string must be a number. */
 	rrtype = strtol(name + 4, &end, 10);
 	if (*end != '\0') {
 		return -1;
@@ -580,7 +579,7 @@ int knot_rrclass_from_string(const char *name, uint16_t *num)
 	*num = rrclass;
 	return 0;
 }
-
+*/
 size_t knot_wireformat_size(unsigned int wire_type)
 {
 	switch(wire_type) {
@@ -601,10 +600,9 @@ size_t knot_wireformat_size(unsigned int wire_type)
 			break;
 	} /* switch */
 }
-
+/*
 int knot_rrtype_is_metatype(uint16_t type)
 {
-	/*! \todo Check if there are some other metatypes. */
 	return (type == KNOT_RRTYPE_ANY
 	        || type == KNOT_RRTYPE_AXFR
 	        || type == KNOT_RRTYPE_IXFR
@@ -612,7 +610,7 @@ int knot_rrtype_is_metatype(uint16_t type)
 	        || type == KNOT_RRTYPE_MAILB
 	        || type == KNOT_RRTYPE_OPT);
 }
-
+*/
 size_t knot_ds_digest_length(uint8_t algorithm)
 {
 	switch (algorithm) {
diff --git a/src/libknot/util/descriptor.h b/src/libknot/util/descriptor.h
index 042552327..62e45572d 100644
--- a/src/libknot/util/descriptor.h
+++ b/src/libknot/util/descriptor.h
@@ -325,9 +325,9 @@ knot_rrtype_descriptor_t *knot_rrtype_descriptor_by_name(const char *name);
  * \return Length of output string.
  * \return -1 if error.
  */
-int knot_rrtype_to_string(const uint16_t rrtype,
-                          char           *out,
-                          const size_t   out_len);
+//int knot_rrtype_to_string(const uint16_t rrtype,
+//                         char           *out,
+//                          const size_t   out_len);
 
 /*!
  * \brief Converts mnemonic string representation of a type to numeric one.
@@ -338,7 +338,7 @@ int knot_rrtype_to_string(const uint16_t rrtype,
  * \return  0 if OK.
  * \return -1 if error.
  */
-int knot_rrtype_from_string(const char *name, uint16_t *num);
+//int knot_rrtype_from_string(const char *name, uint16_t *num);
 
 /*!
  * \brief Converts numeric class representation to the string one.
@@ -350,9 +350,9 @@ int knot_rrtype_from_string(const char *name, uint16_t *num);
  * \return Length of output string.
  * \return -1 if error.
  */
-int knot_rrclass_to_string(const uint16_t rrclass,
-                           char           *out,
-                           const size_t   out_len);
+//int knot_rrclass_to_string(const uint16_t rrclass,
+//                           char           *out,
+//                           const size_t   out_len);
 
 /*!
  * \brief Converts string representation of a class to numeric one.
@@ -363,7 +363,7 @@ int knot_rrclass_to_string(const uint16_t rrclass,
  * \return  0 if OK.
  * \return -1 if error.
  */
-int knot_rrclass_from_string(const char *name, uint16_t *num);
+//int knot_rrclass_from_string(const char *name, uint16_t *num);
 
 /*!
  * \brief Returns size of wireformat type in bytes.
@@ -375,7 +375,7 @@ int knot_rrclass_from_string(const char *name, uint16_t *num);
  */
 size_t knot_wireformat_size(unsigned int wire_type);
 
-int knot_rrtype_is_metatype(uint16_t type);
+//int knot_rrtype_is_metatype(uint16_t type);
 
 size_t knot_ds_digest_length(uint8_t algorithm);
 
diff --git a/src/tests/common/descriptor_tests.c b/src/tests/common/descriptor_tests.c
new file mode 100644
index 000000000..83b4aca22
--- /dev/null
+++ b/src/tests/common/descriptor_tests.c
@@ -0,0 +1,234 @@
+/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tests/common/descriptor_tests.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "common/descriptor_new.h"
+
+#define BUF_LEN 256
+
+static int descriptor_tests_count(int argc, char *argv[]);
+static int descriptor_tests_run(int argc, char *argv[]);
+
+unit_api descriptor_tests_api = {
+	"RR descriptors",
+	&descriptor_tests_count,
+	&descriptor_tests_run
+};
+
+static int descriptor_tests_count(int argc, char *argv[])
+{
+	return 68;
+}
+
+static int descriptor_tests_run(int argc, char *argv[])
+{
+	const    rdata_descriptor_t *descr;
+	char     name[BUF_LEN];
+	int      ret;
+	uint16_t num;
+
+	// Get descriptor, type num to string:
+	// 1. TYPE0
+	descr = get_rdata_descriptor(0);
+	ok(descr->type_name == 0, "get TYPE0 descriptor name");
+	cmp_ok(descr->block_types[0], "==", KNOT_RDATA_WF_REMAINDER,
+	       "get TYPE0 descriptor 1. item type");
+	cmp_ok(descr->block_types[1], "==", KNOT_RDATA_WF_END,
+	       "get TYPE0 descriptor 2. item type");
+
+	ret = knot_rrtype_to_string(0, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get TYPE0 ret");
+	ok(strcmp(name, "TYPE0") == 0, "get TYPE0 name");
+
+	// 2. A
+	descr = get_rdata_descriptor(1);
+	ok(strcmp(descr->type_name, "A") == 0, "get A descriptor name");
+	cmp_ok(descr->block_types[0], "==", 4,
+	       "get A descriptor 1. item type");
+	cmp_ok(descr->block_types[1], "==", KNOT_RDATA_WF_END,
+	       "get A descriptor 2. item type");
+
+	ret = knot_rrtype_to_string(1, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get A ret");
+	ok(strcmp(name, "A") == 0, "get A name");
+
+	// 3. CNAME
+	descr = get_rdata_descriptor(5);
+	ok(strcmp(descr->type_name, "CNAME") == 0, "get CNAME descriptor name");
+	cmp_ok(descr->block_types[0], "==", KNOT_RDATA_WF_COMPRESSED_DNAME,
+	       "get CNAME descriptor 1. item type");
+	cmp_ok(descr->block_types[1], "==", KNOT_RDATA_WF_END,
+	       "get CNAME descriptor 2. item type");
+
+	ret = knot_rrtype_to_string(5, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get CNAME ret");
+	ok(strcmp(name, "CNAME") == 0, "get CNAME name");
+
+	// 4. TYPE38 (A6)
+	descr = get_rdata_descriptor(38);
+	ok(descr->type_name == 0, "get TYPE38 descriptor name");
+	cmp_ok(descr->block_types[0], "==", KNOT_RDATA_WF_REMAINDER,
+	       "get TYPE38 descriptor 1. item type");
+	cmp_ok(descr->block_types[1], "==", KNOT_RDATA_WF_END,
+	       "get TYPE38 descriptor 2. item type");
+
+	ret = knot_rrtype_to_string(38, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get TYPE38 ret");
+	ok(strcmp(name, "TYPE38") == 0, "get TYPE38 name");
+
+	// 5. ANY
+	descr = get_rdata_descriptor(255);
+	ok(strcmp(descr->type_name, "ANY") == 0, "get ANY descriptor name");
+	cmp_ok(descr->block_types[0], "==", KNOT_RDATA_WF_REMAINDER,
+	       "get ANY descriptor 1. item type");
+	cmp_ok(descr->block_types[1], "==", KNOT_RDATA_WF_END,
+	       "get ANY descriptor 2. item type");
+
+	ret = knot_rrtype_to_string(255, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get ANY ret");
+	ok(strcmp(name, "ANY") == 0, "get ANY name");
+
+	// 6. TYPE256
+	descr = get_rdata_descriptor(256);
+	ok(descr->type_name == 0, "get TYPE256 descriptor name");
+	cmp_ok(descr->block_types[0], "==", KNOT_RDATA_WF_REMAINDER,
+	       "get TYPE256 descriptor 1. item type");
+	cmp_ok(descr->block_types[1], "==", KNOT_RDATA_WF_END,
+	       "get TYPE256 descriptor 2. item type");
+
+	ret = knot_rrtype_to_string(256, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get TYPE256 ret");
+	ok(strcmp(name, "TYPE256") == 0, "get TYPE256 name");
+
+
+	// Class num to string:
+	// 7. CLASS0
+	ret = knot_rrclass_to_string(0, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get CLASS0 ret");
+	ok(strcmp(name, "CLASS0") == 0, "get CLASS0 name");
+
+	// 8. IN
+	ret = knot_rrclass_to_string(1, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get IN ret");
+	ok(strcmp(name, "IN") == 0, "get IN name");
+
+	// 9. ANY
+	ret = knot_rrclass_to_string(255, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get ANY ret");
+	ok(strcmp(name, "ANY") == 0, "get ANY name");
+
+	// 10. CLASS65535
+	ret = knot_rrclass_to_string(65535, name, BUF_LEN);
+	cmp_ok(ret, "!=", -1, "get CLASS65535 ret");
+	ok(strcmp(name, "CLASS65535") == 0, "get CLASS65535 name");
+
+	// String to type num:
+	// 11. A
+	ret = knot_rrtype_from_string("A", &num);
+	cmp_ok(ret, "!=", -1, "get A num ret");
+	cmp_ok(num, "==", 1, "get A num");
+
+	// 12. a
+	ret = knot_rrtype_from_string("a", &num);
+	cmp_ok(ret, "!=", -1, "get a num ret");
+	cmp_ok(num, "==", 1, "get a num");
+
+	// 13. AaAa
+	ret = knot_rrtype_from_string("AaAa", &num);
+	cmp_ok(ret, "!=", -1, "get AaAa num ret");
+	cmp_ok(num, "==", 28, "get AaAa num");
+
+	// 14. ""
+	ret = knot_rrtype_from_string("", &num);
+	cmp_ok(ret, "==", -1, "get "" num ret");
+
+	// 15. DUMMY
+	ret = knot_rrtype_from_string("DUMMY", &num);
+	cmp_ok(ret, "==", -1, "get DUMMY num ret");
+
+	// 16. TypE33
+	ret = knot_rrtype_from_string("TypE33", &num);
+	cmp_ok(ret, "!=", -1, "get TypE33 num ret");
+	cmp_ok(num, "==", 33, "get TypE33 num");
+
+	// 17. TYPE
+	ret = knot_rrtype_from_string("TYPE", &num);
+	cmp_ok(ret, "==", -1, "get TYPE num ret");
+
+	// 18. TYPE0
+	ret = knot_rrtype_from_string("TYPE0", &num);
+	cmp_ok(ret, "!=", -1, "get TYPE0 num ret");
+	cmp_ok(num, "==", 0, "get TYPE0 num");
+
+	// 19. TYPE65535
+	ret = knot_rrtype_from_string("TYPE65535", &num);
+	cmp_ok(ret, "!=", -1, "get TYPE65535 num ret");
+	cmp_ok(num, "==", 65535, "get TYPE65535 num");
+
+	// 20. TYPE65536
+	ret = knot_rrtype_from_string("TYPE65536", &num);
+	cmp_ok(ret, "==", -1, "get TYPE65536 num ret");
+
+	// String to class num:
+	// 21. In
+	ret = knot_rrclass_from_string("In", &num);
+	cmp_ok(ret, "!=", -1, "get In num ret");
+	cmp_ok(num, "==", 1, "get In num");
+
+	// 22. ANY
+	ret = knot_rrclass_from_string("ANY", &num);
+	cmp_ok(ret, "!=", -1, "get ANY num ret");
+	cmp_ok(num, "==", 255, "get ANY num");
+
+	// 23. ""
+	ret = knot_rrclass_from_string("", &num);
+	cmp_ok(ret, "==", -1, "get "" num ret");
+
+	// 24. DUMMY
+	ret = knot_rrclass_from_string("DUMMY", &num);
+	cmp_ok(ret, "==", -1, "get DUMMY num ret");
+
+	// 25. CLass33
+	ret = knot_rrclass_from_string("CLass33", &num);
+	cmp_ok(ret, "!=", -1, "get CLass33 num ret");
+	cmp_ok(num, "==", 33, "get CLass33 num");
+
+	// 26. CLASS
+	ret = knot_rrclass_from_string("CLASS", &num);
+	cmp_ok(ret, "==", -1, "get CLASS num ret");
+
+	// 27. CLASS0
+	ret = knot_rrclass_from_string("CLASS0", &num);
+	cmp_ok(ret, "!=", -1, "get CLASS0 num ret");
+	cmp_ok(num, "==", 0, "get CLASS0 num");
+
+	// 28. CLASS65535
+	ret = knot_rrclass_from_string("CLASS65535", &num);
+	cmp_ok(ret, "!=", -1, "get CLASS65535 num ret");
+	cmp_ok(num, "==", 65535, "get CLASS65535 num");
+
+	// 29. CLASS65536
+	ret = knot_rrclass_from_string("CLASS65536", &num);
+	cmp_ok(ret, "==", -1, "get CLASS65536 num ret");
+
+	return 0;
+}
+
diff --git a/src/tests/common/descriptor_tests.h b/src/tests/common/descriptor_tests.h
new file mode 100644
index 000000000..7b7f861a9
--- /dev/null
+++ b/src/tests/common/descriptor_tests.h
@@ -0,0 +1,25 @@
+/*  Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _KNOTD_DESCRIPTOR_TESTS_H_
+#define _KNOTD_DESCRIPTOR_TESTS_H_
+
+#include "common/libtap/tap_unit.h"
+
+/* Unit API. */
+unit_api descriptor_tests_api;
+
+#endif /* _KNOTD_DESCRIPTOR_TESTS_H_ */
diff --git a/src/tests/unittests_main.c b/src/tests/unittests_main.c
index c4c220ffb..bd59ab969 100644
--- a/src/tests/unittests_main.c
+++ b/src/tests/unittests_main.c
@@ -26,6 +26,7 @@
 #include "tests/common/fdset_tests.h"
 #include "tests/common/base64_tests.h"
 #include "tests/common/base32hex_tests.h"
+#include "tests/common/descriptor_tests.h"
 #include "tests/knot/dthreads_tests.h"
 #include "tests/knot/journal_tests.h"
 #include "tests/knot/server_tests.h"
@@ -54,6 +55,7 @@ int main(int argc, char *argv[])
 	        &fdset_tests_api,	//! FDSET polling wrapper
 	        &base64_tests_api,	//! Base64 encoding
 	        &base32hex_tests_api,	//! Base32hex encoding
+	        &descriptor_tests_api,	//! RR descriptors
 
 	        /* Library. */
 	        &wire_tests_api,
-- 
GitLab