]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4199. [protocol] Add support for NINFO, RKEY. [RT #40547] [RT #40563]
authorMark Andrews <marka@isc.org>
Thu, 10 Sep 2015 07:07:05 +0000 (17:07 +1000)
committerMark Andrews <marka@isc.org>
Thu, 10 Sep 2015 07:07:05 +0000 (17:07 +1000)
CHANGES
bin/tests/system/genzone.sh
bin/tests/system/rrchecker/typelist.good
bin/tests/system/xfer/dig1.good
bin/tests/system/xfer/dig2.good
doc/arm/notes.xml
lib/dns/rdata.c
lib/dns/rdata/generic/ninfo_56.c [new file with mode: 0644]
lib/dns/rdata/generic/ninfo_56.h [new file with mode: 0644]
lib/dns/rdata/generic/spf_99.c
lib/dns/rdata/generic/txt_16.c

diff --git a/CHANGES b/CHANGES
index 8499b441f6f6c3335862c3e121a00478dd26c370..5fdb6c3fe6b443c9c47d3d78712ea54d21b9aadd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-4199.  [protocol]      Add support for RKEY. [RT #40563]
+4199.  [protocol]      Add support for NINFO, RKEY. [RT #40547] [RT #40563]
 
 4198.  [placeholder]
 
index c0dc872db778b74d5d6eb00c9238ae6216778ef2..f307ff0f4894c5a8b18d5832975d8ae27612a6ed 100644 (file)
@@ -241,6 +241,23 @@ dnskey01           DNSKEY  512 ( 255 1 AQMFD5raczCJHViKtLYhWGz8hMY
                                sENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esg
                                a60zyGW6LFe9r8n6paHrlG5ojqf0BaqHT+8= )
 
+; type 56
+ninfo01                        NINFO   "foo"
+ninfo02                        NINFO   "foo" "bar"
+ninfo03                        NINFO   foo
+ninfo04                        NINFO   foo bar
+ninfo05                        NINFO   "foo bar"
+ninfo06                        NINFO   "foo\032bar"
+ninfo07                        NINFO   foo\032bar
+ninfo08                        NINFO   "foo\010bar"
+ninfo09                        NINFO   foo\010bar
+ninfo10                        NINFO   foo\ bar
+ninfo11                        NINFO   "\"foo\""
+ninfo12                        NINFO   \"foo\"
+ninfo13                        NINFO   "foo;"
+ninfo14                        NINFO   "foo\;"
+ninfo15                        NINFO   "bar\\;"
+
 ; type 57
 rkey01                 RKEY    512 ( 255 1 AQMFD5raczCJHViKtLYhWGz8hMY
                                9UGRuniJDBzC7w0aRyzWZriO6i2odGWWQVucZqKV
index b8818885e335d54d0a10288633748d0eda0c35ce..7d22ab23a85b295bc4bf0f0e7b7fa4f22ac556e1 100644 (file)
@@ -49,6 +49,7 @@ NSEC3
 NSEC3PARAM
 TLSA
 HIP
+NINFO
 RKEY
 CDS
 CDNSKEY
index 1fc60508b94383d91bee6bbf6083d1a21eab1d46..062e9e4a19795de473e53a8e13bcf5c024dd6875 100644 (file)
@@ -57,6 +57,21 @@ mx01.example.                3600    IN      MX      10 mail.example.
 mx02.example.          3600    IN      MX      10 .
 naptr01.example.       3600    IN      NAPTR   0 0 "" "" "" .
 naptr02.example.       3600    IN      NAPTR   65535 65535 "blurgh" "blorf" "blllbb" foo.
+ninfo01.example.       3600    IN      NINFO   "foo"
+ninfo02.example.       3600    IN      NINFO   "foo" "bar"
+ninfo03.example.       3600    IN      NINFO   "foo"
+ninfo04.example.       3600    IN      NINFO   "foo" "bar"
+ninfo05.example.       3600    IN      NINFO   "foo bar"
+ninfo06.example.       3600    IN      NINFO   "foo bar"
+ninfo07.example.       3600    IN      NINFO   "foo bar"
+ninfo08.example.       3600    IN      NINFO   "foo\010bar"
+ninfo09.example.       3600    IN      NINFO   "foo\010bar"
+ninfo10.example.       3600    IN      NINFO   "foo bar"
+ninfo11.example.       3600    IN      NINFO   "\"foo\""
+ninfo12.example.       3600    IN      NINFO   "\"foo\""
+ninfo13.example.       3600    IN      NINFO   "foo;"
+ninfo14.example.       3600    IN      NINFO   "foo;"
+ninfo15.example.       3600    IN      NINFO   "bar\\;"
 ns2.example.           3600    IN      A       10.53.0.2
 ns3.example.           3600    IN      A       10.53.0.3
 nsap-ptr01.example.    3600    IN      NSAP-PTR .
index 4915920ec0dd6db0ce04fbf6d5cf88b26c482a85..17bdfc7a491452464c4e000ad98e6c0a8dae2d51 100644 (file)
@@ -57,6 +57,21 @@ mx01.example.                3600    IN      MX      10 mail.example.
 mx02.example.          3600    IN      MX      10 .
 naptr01.example.       3600    IN      NAPTR   0 0 "" "" "" .
 naptr02.example.       3600    IN      NAPTR   65535 65535 "blurgh" "blorf" "blllbb" foo.
+ninfo01.example.       3600    IN      NINFO   "foo"
+ninfo02.example.       3600    IN      NINFO   "foo" "bar"
+ninfo03.example.       3600    IN      NINFO   "foo"
+ninfo04.example.       3600    IN      NINFO   "foo" "bar"
+ninfo05.example.       3600    IN      NINFO   "foo bar"
+ninfo06.example.       3600    IN      NINFO   "foo bar"
+ninfo07.example.       3600    IN      NINFO   "foo bar"
+ninfo08.example.       3600    IN      NINFO   "foo\010bar"
+ninfo09.example.       3600    IN      NINFO   "foo\010bar"
+ninfo10.example.       3600    IN      NINFO   "foo bar"
+ninfo11.example.       3600    IN      NINFO   "\"foo\""
+ninfo12.example.       3600    IN      NINFO   "\"foo\""
+ninfo13.example.       3600    IN      NINFO   "foo;"
+ninfo14.example.       3600    IN      NINFO   "foo;"
+ninfo15.example.       3600    IN      NINFO   "bar\\;"
 ns2.example.           3600    IN      A       10.53.0.2
 ns3.example.           3600    IN      A       10.53.0.3
 nsap-ptr01.example.    3600    IN      NSAP-PTR .
index 453e625a4bee2a8c1610180771a3c77422dc4879..bc63ac3d27dcd89ec984ac943b90f14f16b6cda5 100644 (file)
       </listitem>
       <listitem>
        <para>
-         The following types have been implemented: RKEY.
+         The following types have been implemented: NINFO, RKEY.
        </para>
       </listitem>
     </itemizedlist>
index 5a7474ec19e174acb493c917f49291f7e118c9b8..76b35d17c02d38e6f9654ab12348c177042a399f 100644 (file)
@@ -237,6 +237,33 @@ generic_tostruct_key(ARGS_TOSTRUCT);
 static inline void
 generic_freestruct_key(ARGS_FREESTRUCT);
 
+static isc_result_t
+generic_fromtext_txt(ARGS_FROMTEXT);
+
+static isc_result_t
+generic_totext_txt(ARGS_TOTEXT);
+
+static isc_result_t
+generic_fromwire_txt(ARGS_FROMWIRE);
+
+static isc_result_t
+generic_fromstruct_txt(ARGS_FROMSTRUCT);
+
+static isc_result_t
+generic_tostruct_txt(ARGS_TOSTRUCT);
+
+static void
+generic_freestruct_txt(ARGS_FREESTRUCT);
+
+static isc_result_t
+generic_txt_first(dns_rdata_txt_t *txt);
+
+static isc_result_t
+generic_txt_next(dns_rdata_txt_t *txt);
+
+static isc_result_t
+generic_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string);
+
 /*% INT16 Size */
 #define NS_INT16SZ     2
 /*% IPv6 Address Size */
diff --git a/lib/dns/rdata/generic/ninfo_56.c b/lib/dns/rdata/generic/ninfo_56.c
new file mode 100644 (file)
index 0000000..f31f47e
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC 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.
+ */
+
+#ifndef RDATA_GENERIC_NINFO_56_C
+#define RDATA_GENERIC_NINFO_56_C
+
+#define RRTYPE_NINFO_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_ninfo(ARGS_FROMTEXT) {
+
+       REQUIRE(type == dns_rdatatype_ninfo);
+
+       UNUSED(type);
+       UNUSED(rdclass);
+       UNUSED(origin);
+       UNUSED(options);
+       UNUSED(callbacks);
+
+       return (generic_fromtext_txt(rdclass, type, lexer, origin, options,
+                                    target, callbacks));
+}
+
+static inline isc_result_t
+totext_ninfo(ARGS_TOTEXT) {
+
+       UNUSED(tctx);
+
+       REQUIRE(rdata->type == dns_rdatatype_ninfo);
+
+       return (generic_totext_txt(rdata, tctx, target));
+}
+
+static inline isc_result_t
+fromwire_ninfo(ARGS_FROMWIRE) {
+
+       REQUIRE(type == dns_rdatatype_ninfo);
+
+       UNUSED(type);
+       UNUSED(dctx);
+       UNUSED(rdclass);
+       UNUSED(options);
+
+       return (generic_fromwire_txt(rdclass, type, source, dctx, options,
+                                    target));
+}
+
+static inline isc_result_t
+towire_ninfo(ARGS_TOWIRE) {
+
+       REQUIRE(rdata->type == dns_rdatatype_ninfo);
+
+       UNUSED(cctx);
+
+       return (mem_tobuffer(target, rdata->data, rdata->length));
+}
+
+static inline int
+compare_ninfo(ARGS_COMPARE) {
+       isc_region_t r1;
+       isc_region_t r2;
+
+       REQUIRE(rdata1->type == rdata2->type);
+       REQUIRE(rdata1->rdclass == rdata2->rdclass);
+       REQUIRE(rdata1->type == dns_rdatatype_ninfo);
+
+       dns_rdata_toregion(rdata1, &r1);
+       dns_rdata_toregion(rdata2, &r2);
+       return (isc_region_compare(&r1, &r2));
+}
+
+static inline isc_result_t
+fromstruct_ninfo(ARGS_FROMSTRUCT) {
+
+       REQUIRE(type == dns_rdatatype_ninfo);
+
+       return (generic_fromstruct_txt(rdclass, type, source, target));
+}
+
+static inline isc_result_t
+tostruct_ninfo(ARGS_TOSTRUCT) {
+       dns_rdata_ninfo_t *txt = target;
+
+       REQUIRE(rdata->type == dns_rdatatype_ninfo);
+
+       txt->common.rdclass = rdata->rdclass;
+       txt->common.rdtype = rdata->type;
+       ISC_LINK_INIT(&txt->common, link);
+
+       return (generic_tostruct_txt(rdata, target, mctx));
+}
+
+static inline void
+freestruct_ninfo(ARGS_FREESTRUCT) {
+       dns_rdata_ninfo_t *ninfo = source;
+
+       REQUIRE(source != NULL);
+       REQUIRE(ninfo->common.rdtype == dns_rdatatype_ninfo);
+
+       generic_freestruct_txt(source);
+}
+
+static inline isc_result_t
+additionaldata_ninfo(ARGS_ADDLDATA) {
+       REQUIRE(rdata->type == dns_rdatatype_ninfo);
+
+       UNUSED(rdata);
+       UNUSED(add);
+       UNUSED(arg);
+
+       return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_ninfo(ARGS_DIGEST) {
+       isc_region_t r;
+
+       REQUIRE(rdata->type == dns_rdatatype_ninfo);
+
+       dns_rdata_toregion(rdata, &r);
+
+       return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_ninfo(ARGS_CHECKOWNER) {
+
+       REQUIRE(type == dns_rdatatype_ninfo);
+
+       UNUSED(name);
+       UNUSED(type);
+       UNUSED(rdclass);
+       UNUSED(wildcard);
+
+       return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_ninfo(ARGS_CHECKNAMES) {
+
+       REQUIRE(rdata->type == dns_rdatatype_ninfo);
+
+       UNUSED(rdata);
+       UNUSED(owner);
+       UNUSED(bad);
+
+       return (ISC_TRUE);
+}
+
+static inline isc_result_t
+casecompare_ninfo(ARGS_COMPARE) {
+       return (compare_ninfo(rdata1, rdata2));
+}
+
+isc_result_t
+dns_rdata_ninfo_first(dns_rdata_ninfo_t *ninfo) {
+
+       REQUIRE(ninfo != NULL);
+       REQUIRE(ninfo->common.rdtype == dns_rdatatype_ninfo);
+
+       return (generic_txt_first(ninfo));
+}
+
+isc_result_t
+dns_rdata_ninfo_next(dns_rdata_ninfo_t *ninfo) {
+
+       REQUIRE(ninfo != NULL);
+       REQUIRE(ninfo->common.rdtype == dns_rdatatype_ninfo);
+
+       return (generic_txt_next(ninfo));
+}
+
+isc_result_t
+dns_rdata_ninfo_current(dns_rdata_ninfo_t *ninfo,
+                       dns_rdata_ninfo_string_t *string)
+{
+
+       REQUIRE(ninfo != NULL);
+       REQUIRE(ninfo->common.rdtype == dns_rdatatype_ninfo);
+
+       return (generic_txt_current(ninfo, string));
+}
+#endif /* RDATA_GENERIC_NINFO_56_C */
diff --git a/lib/dns/rdata/generic/ninfo_56.h b/lib/dns/rdata/generic/ninfo_56.h
new file mode 100644 (file)
index 0000000..f0f09ec
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC 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.
+ */
+
+/* */
+#ifndef GENERIC_NINFO_56_H
+#define GENERIC_NINFO_56_H 1
+
+typedef struct dns_rdata_txt_string dns_rdata_ninfo_string_t;
+
+typedef struct dns_rdata_txt dns_rdata_ninfo_t;
+
+/*
+ * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done
+ * via rdatastructpre.h and rdatastructsuf.h.
+ */
+
+isc_result_t
+dns_rdata_ninfo_first(dns_rdata_ninfo_t *);
+
+isc_result_t
+dns_rdata_ninfo_next(dns_rdata_ninfo_t *);
+
+isc_result_t
+dns_rdata_ninfo_current(dns_rdata_ninfo_t *, dns_rdata_ninfo_string_t *);
+
+#endif /* GENERIC_NINFO_16_H */
index 8ad4f02b9af4faa2f1cde77e4908b5dedfe55133..4e886677e0cd7fb7b59026f58559a8284832e18c 100644 (file)
@@ -26,8 +26,6 @@
 
 static inline isc_result_t
 fromtext_spf(ARGS_FROMTEXT) {
-       isc_token_t token;
-       int strings;
 
        REQUIRE(type == dns_rdatatype_spf);
 
@@ -37,44 +35,22 @@ fromtext_spf(ARGS_FROMTEXT) {
        UNUSED(options);
        UNUSED(callbacks);
 
-       strings = 0;
-       for (;;) {
-               RETERR(isc_lex_getmastertoken(lexer, &token,
-                                             isc_tokentype_qstring,
-                                             ISC_TRUE));
-               if (token.type != isc_tokentype_qstring &&
-                   token.type != isc_tokentype_string)
-                       break;
-               RETTOK(txt_fromtext(&token.value.as_textregion, target));
-               strings++;
-       }
-       /* Let upper layer handle eol/eof. */
-       isc_lex_ungettoken(lexer, &token);
-       return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS);
+       return (generic_fromtext_txt(rdclass, type, lexer, origin, options,
+                                     target, callbacks));
 }
 
 static inline isc_result_t
 totext_spf(ARGS_TOTEXT) {
-       isc_region_t region;
 
        UNUSED(tctx);
 
        REQUIRE(rdata->type == dns_rdatatype_spf);
 
-       dns_rdata_toregion(rdata, &region);
-
-       while (region.length > 0) {
-               RETERR(txt_totext(&region, ISC_TRUE, target));
-               if (region.length > 0)
-                       RETERR(str_totext(" ", target));
-       }
-
-       return (ISC_R_SUCCESS);
+       return (generic_totext_txt(rdata, tctx, target));
 }
 
 static inline isc_result_t
 fromwire_spf(ARGS_FROMWIRE) {
-       isc_result_t result;
 
        REQUIRE(type == dns_rdatatype_spf);
 
@@ -83,29 +59,18 @@ fromwire_spf(ARGS_FROMWIRE) {
        UNUSED(rdclass);
        UNUSED(options);
 
-       do {
-               result = txt_fromwire(source, target);
-               if (result != ISC_R_SUCCESS)
-                       return (result);
-       } while (!buffer_empty(source));
-       return (ISC_R_SUCCESS);
+       return (generic_fromwire_txt(rdclass, type, source, dctx, options,
+                                     target));
 }
 
 static inline isc_result_t
 towire_spf(ARGS_TOWIRE) {
-       isc_region_t region;
 
        REQUIRE(rdata->type == dns_rdatatype_spf);
 
        UNUSED(cctx);
 
-       isc_buffer_availableregion(target, &region);
-       if (region.length < rdata->length)
-               return (ISC_R_NOSPACE);
-
-       memmove(region.base, rdata->data, rdata->length);
-       isc_buffer_add(target, rdata->length);
-       return (ISC_R_SUCCESS);
+       return (mem_tobuffer(target, rdata->data, rdata->length));
 }
 
 static inline int
@@ -124,53 +89,24 @@ compare_spf(ARGS_COMPARE) {
 
 static inline isc_result_t
 fromstruct_spf(ARGS_FROMSTRUCT) {
-       dns_rdata_spf_t *txt = source;
-       isc_region_t region;
-       isc_uint8_t length;
 
        REQUIRE(type == dns_rdatatype_spf);
-       REQUIRE(source != NULL);
-       REQUIRE(txt->common.rdtype == type);
-       REQUIRE(txt->common.rdclass == rdclass);
-       REQUIRE(txt->txt != NULL && txt->txt_len != 0);
 
-       UNUSED(type);
-       UNUSED(rdclass);
-
-       region.base = txt->txt;
-       region.length = txt->txt_len;
-       while (region.length > 0) {
-               length = uint8_fromregion(&region);
-               isc_region_consume(&region, 1);
-               if (region.length <= length)
-                       return (ISC_R_UNEXPECTEDEND);
-               isc_region_consume(&region, length);
-       }
-
-       return (mem_tobuffer(target, txt->txt, txt->txt_len));
+       return (generic_fromstruct_txt(rdclass, type, source, target));
 }
 
 static inline isc_result_t
 tostruct_spf(ARGS_TOSTRUCT) {
-       dns_rdata_spf_t *txt = target;
-       isc_region_t r;
+       dns_rdata_spf_t *spf = target;
 
        REQUIRE(rdata->type == dns_rdatatype_spf);
        REQUIRE(target != NULL);
 
-       txt->common.rdclass = rdata->rdclass;
-       txt->common.rdtype = rdata->type;
-       ISC_LINK_INIT(&txt->common, link);
+       spf->common.rdclass = rdata->rdclass;
+       spf->common.rdtype = rdata->type;
+       ISC_LINK_INIT(&spf->common, link);
 
-       dns_rdata_toregion(rdata, &r);
-       txt->txt_len = r.length;
-       txt->txt = mem_maybedup(mctx, r.base, r.length);
-       if (txt->txt == NULL)
-               return (ISC_R_NOMEMORY);
-
-       txt->offset = 0;
-       txt->mctx = mctx;
-       return (ISC_R_SUCCESS);
+       return (generic_tostruct_txt(rdata, target, mctx));
 }
 
 static inline void
@@ -180,12 +116,7 @@ freestruct_spf(ARGS_FREESTRUCT) {
        REQUIRE(source != NULL);
        REQUIRE(txt->common.rdtype == dns_rdatatype_spf);
 
-       if (txt->mctx == NULL)
-               return;
-
-       if (txt->txt != NULL)
-               isc_mem_free(txt->mctx, txt->txt);
-       txt->mctx = NULL;
+       generic_freestruct_txt(source);
 }
 
 static inline isc_result_t
index aa7c3a0ab138df082ede072b7a8ec1c296e2d80a..2ebd46c3169cbbb29f00a6cb751e4de576b1acf3 100644 (file)
@@ -15,8 +15,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: txt_16.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */
-
 /* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */
 
 #ifndef RDATA_GENERIC_TXT_16_C
 #define RRTYPE_TXT_ATTRIBUTES (0)
 
 static inline isc_result_t
-fromtext_txt(ARGS_FROMTEXT) {
+generic_fromtext_txt(ARGS_FROMTEXT) {
        isc_token_t token;
        int strings;
 
-       REQUIRE(type == dns_rdatatype_txt);
-
        UNUSED(type);
        UNUSED(rdclass);
        UNUSED(origin);
@@ -61,13 +57,11 @@ fromtext_txt(ARGS_FROMTEXT) {
 }
 
 static inline isc_result_t
-totext_txt(ARGS_TOTEXT) {
+generic_totext_txt(ARGS_TOTEXT) {
        isc_region_t region;
 
        UNUSED(tctx);
 
-       REQUIRE(rdata->type == dns_rdatatype_txt);
-
        dns_rdata_toregion(rdata, &region);
 
        while (region.length > 0) {
@@ -80,11 +74,9 @@ totext_txt(ARGS_TOTEXT) {
 }
 
 static inline isc_result_t
-fromwire_txt(ARGS_FROMWIRE) {
+generic_fromwire_txt(ARGS_FROMWIRE) {
        isc_result_t result;
 
-       REQUIRE(type == dns_rdatatype_txt);
-
        UNUSED(type);
        UNUSED(dctx);
        UNUSED(rdclass);
@@ -98,21 +90,40 @@ fromwire_txt(ARGS_FROMWIRE) {
        return (ISC_R_SUCCESS);
 }
 
+static inline isc_result_t
+fromtext_txt(ARGS_FROMTEXT) {
+
+       REQUIRE(type == dns_rdatatype_txt);
+
+       return (generic_fromtext_txt(rdclass, type, lexer, origin, options,
+                                    target, callbacks));
+}
+
+static inline isc_result_t
+totext_txt(ARGS_TOTEXT) {
+
+       REQUIRE(rdata->type == dns_rdatatype_txt);
+
+       return (generic_totext_txt(rdata, tctx, target));
+}
+
+static inline isc_result_t
+fromwire_txt(ARGS_FROMWIRE) {
+
+       REQUIRE(type == dns_rdatatype_txt);
+
+       return (generic_fromwire_txt(rdclass, type, source, dctx, options,
+                                    target));
+}
+
 static inline isc_result_t
 towire_txt(ARGS_TOWIRE) {
-       isc_region_t region;
 
        REQUIRE(rdata->type == dns_rdatatype_txt);
 
        UNUSED(cctx);
 
-       isc_buffer_availableregion(target, &region);
-       if (region.length < rdata->length)
-               return (ISC_R_NOSPACE);
-
-       memmove(region.base, rdata->data, rdata->length);
-       isc_buffer_add(target, rdata->length);
-       return (ISC_R_SUCCESS);
+       return (mem_tobuffer(target, rdata->data, rdata->length));
 }
 
 static inline int
@@ -130,12 +141,11 @@ compare_txt(ARGS_COMPARE) {
 }
 
 static inline isc_result_t
-fromstruct_txt(ARGS_FROMSTRUCT) {
+generic_fromstruct_txt(ARGS_FROMSTRUCT) {
        dns_rdata_txt_t *txt = source;
        isc_region_t region;
        isc_uint8_t length;
 
-       REQUIRE(type == dns_rdatatype_txt);
        REQUIRE(source != NULL);
        REQUIRE(txt->common.rdtype == type);
        REQUIRE(txt->common.rdclass == rdclass);
@@ -158,16 +168,14 @@ fromstruct_txt(ARGS_FROMSTRUCT) {
 }
 
 static inline isc_result_t
-tostruct_txt(ARGS_TOSTRUCT) {
+generic_tostruct_txt(ARGS_TOSTRUCT) {
        dns_rdata_txt_t *txt = target;
        isc_region_t r;
 
-       REQUIRE(rdata->type == dns_rdatatype_txt);
        REQUIRE(target != NULL);
-
-       txt->common.rdclass = rdata->rdclass;
-       txt->common.rdtype = rdata->type;
-       ISC_LINK_INIT(&txt->common, link);
+       REQUIRE(txt->common.rdclass == rdata->rdclass);
+       REQUIRE(txt->common.rdtype == rdata->type);
+       REQUIRE(!ISC_LINK_LINKED(&txt->common, link));
 
        dns_rdata_toregion(rdata, &r);
        txt->txt_len = r.length;
@@ -181,11 +189,10 @@ tostruct_txt(ARGS_TOSTRUCT) {
 }
 
 static inline void
-freestruct_txt(ARGS_FREESTRUCT) {
+generic_freestruct_txt(ARGS_FREESTRUCT) {
        dns_rdata_txt_t *txt = source;
 
        REQUIRE(source != NULL);
-       REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
 
        if (txt->mctx == NULL)
                return;
@@ -195,6 +202,38 @@ freestruct_txt(ARGS_FREESTRUCT) {
        txt->mctx = NULL;
 }
 
+static inline isc_result_t
+fromstruct_txt(ARGS_FROMSTRUCT) {
+
+       REQUIRE(type == dns_rdatatype_txt);
+
+       return (generic_fromstruct_txt(rdclass, type, source, target));
+}
+
+static inline isc_result_t
+tostruct_txt(ARGS_TOSTRUCT) {
+       dns_rdata_txt_t *txt = target;
+
+       REQUIRE(rdata->type == dns_rdatatype_txt);
+       REQUIRE(target != NULL);
+
+       txt->common.rdclass = rdata->rdclass;
+       txt->common.rdtype = rdata->type;
+       ISC_LINK_INIT(&txt->common, link);
+
+       return (generic_tostruct_txt(rdata, target, mctx));
+}
+
+static inline void
+freestruct_txt(ARGS_FREESTRUCT) {
+       dns_rdata_txt_t *txt = source;
+
+       REQUIRE(source != NULL);
+       REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
+
+       generic_freestruct_txt(source);
+}
+
 static inline isc_result_t
 additionaldata_txt(ARGS_ADDLDATA) {
        REQUIRE(rdata->type == dns_rdatatype_txt);
@@ -247,11 +286,10 @@ casecompare_txt(ARGS_COMPARE) {
        return (compare_txt(rdata1, rdata2));
 }
 
-isc_result_t
-dns_rdata_txt_first(dns_rdata_txt_t *txt) {
+static isc_result_t
+generic_txt_first(dns_rdata_txt_t *txt) {
 
        REQUIRE(txt != NULL);
-       REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
        REQUIRE(txt->txt != NULL || txt->txt_len == 0);
 
        if (txt->txt_len == 0)
@@ -261,13 +299,12 @@ dns_rdata_txt_first(dns_rdata_txt_t *txt) {
        return (ISC_R_SUCCESS);
 }
 
-isc_result_t
-dns_rdata_txt_next(dns_rdata_txt_t *txt) {
+static isc_result_t
+generic_txt_next(dns_rdata_txt_t *txt) {
        isc_region_t r;
        isc_uint8_t length;
 
        REQUIRE(txt != NULL);
-       REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
        REQUIRE(txt->txt != NULL && txt->txt_len != 0);
 
        INSIST(txt->offset + 1 <= txt->txt_len);
@@ -281,13 +318,12 @@ dns_rdata_txt_next(dns_rdata_txt_t *txt) {
        return (ISC_R_SUCCESS);
 }
 
-isc_result_t
-dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) {
+static isc_result_t
+generic_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) {
        isc_region_t r;
 
        REQUIRE(txt != NULL);
        REQUIRE(string != NULL);
-       REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
        REQUIRE(txt->txt != NULL);
        REQUIRE(txt->offset < txt->txt_len);
 
@@ -302,4 +338,31 @@ dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) {
 
        return (ISC_R_SUCCESS);
 }
+
+isc_result_t
+dns_rdata_txt_first(dns_rdata_txt_t *txt) {
+
+       REQUIRE(txt != NULL);
+       REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
+
+       return (generic_txt_first(txt));
+}
+
+isc_result_t
+dns_rdata_txt_next(dns_rdata_txt_t *txt) {
+
+       REQUIRE(txt != NULL);
+       REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
+
+       return (generic_txt_next(txt));
+}
+
+isc_result_t
+dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) {
+
+       REQUIRE(txt != NULL);
+       REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
+
+       return (generic_txt_current(txt, string));
+}
 #endif /* RDATA_GENERIC_TXT_16_C */