diff --git a/CHANGES b/CHANGES index 177ee33444..7cfca07141 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3004. [func] DNS64 reverse support. [RT #22769] + 3003. [experimental] Added update-policy match type "external", enabliing named to defer the decision of whether to allow a dynamic update to an external daemon. diff --git a/bin/named/builtin.c b/bin/named/builtin.c index dae6d635bb..ef320ddb1d 100644 --- a/bin/named/builtin.c +++ b/bin/named/builtin.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: builtin.c,v 1.17 2010/08/03 23:46:39 tbox Exp $ */ +/* $Id: builtin.c,v 1.18 2011/01/07 04:31:38 marka Exp $ */ /*! \file * \brief @@ -47,6 +47,7 @@ static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup); static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup); static isc_result_t do_id_lookup(dns_sdblookup_t *lookup); static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup); +static isc_result_t do_dns64_lookup(dns_sdblookup_t *lookup); /* * We can't use function pointers as the db_data directly @@ -65,9 +66,179 @@ static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL }; static builtin_t authors_builtin = { do_authors_lookup, NULL, NULL }; static builtin_t id_builtin = { do_id_lookup, NULL, NULL }; static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL }; +static builtin_t dns64_builtin = { do_dns64_lookup, NULL, NULL }; static dns_sdbimplementation_t *builtin_impl; +static const char hex[] = "0123456789abcdef"; +static const char HEX[] = "0123456789ABCDEF"; + +static isc_result_t +dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) { + size_t zlen, nlen, j; + const char *s; + unsigned char v[16]; + unsigned int i; + char reverse[sizeof("123.123.123.123.in-addr.arpa.")]; + + /* + * The sum the length of the relative name and the length of the zone + * name for a IPv6 reverse lookup comes to 71. + * + * The reverse of 2001::10.0.0.1 (dns64 2001::/96) has a zone of + * "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.2.ip6.arpa" + * and a name of "1.0.0.0.0.0.a.0". The sum of the lengths of these + * two strings is 71. + * + * The minimum length for a ip6.arpa zone name is 8. + * + * The length of name should always be odd as we are expecting + * a series of nibbles. + */ + zlen = strlen(zone); + nlen = strlen(name); + if ((zlen + nlen) > 71U || zlen < 8U || (nlen % 2) != 1) + return (ISC_R_NOTFOUND); + + /* + * We assume the zone name is well formed. + */ + + /* + * XXXMPA We could check the dns64 suffix here if we need to. + */ + /* + * Check that name is a series of nibbles. + * Compute the byte values that correspond to the nibbles as we go. + * + * Shift the final result 4 bits, by setting 'i' to 1, if we if we + * have a odd number of nibbles so that "must be zero" tests below + * are byte aligned and we correctly return ISC_R_NOTFOUND or + * ISC_R_SUCCESS. We will not generate a CNAME in this case. + */ + i = (nlen % 4) == 1 ? 1 : 0; + j = nlen; + memset(v, 0, sizeof(v)); + while (j >= 1) { + INSIST((i/2) < sizeof(v)); + if (j > 1 && name[1] != '.') + return (ISC_R_NOTFOUND); + v[i/2] >>= 4; + if ((s = strchr(hex, name[0])) != NULL) + v[i/2] |= (s - hex) << 4; + else if ((s = strchr(HEX, name[0])) != NULL) + v[i/2] |= (s - HEX) << 4; + else + return (ISC_R_NOTFOUND); + if (j > 1) + j -= 2; + else + j -= 1; + name += 2; + i++; + } + + /* + * If we get here then we know name only consisted of nibbles. + * Now we need to determine if the name exists or not and whether + * it corresponds to a empty node in the zone or there should be + * a CNAME. + */ + switch (zlen) { + case 24: /* prefix len 32 */ + /* + * If the total length is not 71 then this is a empty node + * so return success. + */ + if (nlen + zlen != 71U) + return (ISC_R_SUCCESS); + snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", + v[8], v[9], v[10], v[11]); + break; + case 28: /* prefix len 40 */ + /* + * The nibbles that map to this byte must be zero for 'name' + * to exist in the zone. + */ + if (nlen > 11 && v[nlen/4 - 3] != 0) + return (ISC_R_NOTFOUND); + /* + * If the total length is not 71 then this is a empty node + * so return success. + */ + if (nlen + zlen != 71U) + return (ISC_R_SUCCESS); + snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", + v[6], v[8], v[9], v[10]); + break; + case 32: /* prefix len 48 */ + /* + * The nibbles that map to this byte must be zero for 'name' + * to exist in the zone. + */ + if (nlen > 7 && v[nlen/4 - 2] != 0) + return (ISC_R_NOTFOUND); + /* + * If the total length is not 71 then this is a empty node + * so return success. + */ + if (nlen + zlen != 71U) + return (ISC_R_SUCCESS); + snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", + v[5], v[6], v[8], v[9]); + break; + case 36: /* prefix len 56 */ + /* + * The nibbles that map to this byte must be zero for 'name' + * to exist in the zone. + */ + if (nlen > 3 && v[nlen/4 - 1] != 0) + return (ISC_R_NOTFOUND); + /* + * If the total length is not 71 then this is a empty node + * so return success. + */ + if (nlen + zlen != 71U) + return (ISC_R_SUCCESS); + snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", + v[4], v[5], v[6], v[8]); + break; + case 40: /* prefix len 64 */ + /* + * The nibbles that map to this byte must be zero for 'name' + * to exist in the zone. + */ + if (v[nlen/4] != 0) + return (ISC_R_NOTFOUND); + /* + * If the total length is not 71 then this is a empty node + * so return success. + */ + if (nlen + zlen != 71U) + return (ISC_R_SUCCESS); + snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", + v[3], v[4], v[5], v[6]); + break; + case 56: /* prefix len 96 */ + /* + * If the total length is not 71 then this is a empty node + * so return success. + */ + if (nlen + zlen != 71U) + return (ISC_R_SUCCESS); + snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", + v[0], v[1], v[2], v[3]); + break; + default: + /* + * This should never be reached unless someone adds a + * zone declaration with this internal type to named.conf. + */ + return (ISC_R_NOTFOUND); + } + return (dns_sdb_putrr(lookup, "CNAME", 600, reverse)); +} + static isc_result_t builtin_lookup(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *lookup) @@ -78,6 +249,8 @@ builtin_lookup(const char *zone, const char *name, void *dbdata, if (strcmp(name, "@") == 0) return (b->do_lookup(lookup)); + else if (b->do_lookup == do_dns64_lookup) + return (dns64_cname(zone, name, lookup)); else return (ISC_R_NOTFOUND); } @@ -175,6 +348,12 @@ do_id_lookup(dns_sdblookup_t *lookup) { return (put_txt(lookup, ns_g_server->server_id)); } +static isc_result_t +do_dns64_lookup(dns_sdblookup_t *lookup) { + UNUSED(lookup); + return (ISC_R_SUCCESS); +} + static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup) { @@ -222,7 +401,7 @@ builtin_create(const char *zone, int argc, char **argv, UNUSED(zone); UNUSED(driverdata); - if (strcmp(argv[0], "empty") == 0) { + if (strcmp(argv[0], "empty") == 0 || strcmp(argv[0], "dns64") == 0) { if (argc != 3) return (DNS_R_SYNTAX); } else if (argc != 1) @@ -236,7 +415,8 @@ builtin_create(const char *zone, int argc, char **argv, *dbdata = &authors_builtin; else if (strcmp(argv[0], "id") == 0) *dbdata = &id_builtin; - else if (strcmp(argv[0], "empty") == 0) { + else if (strcmp(argv[0], "empty") == 0 || + strcmp(argv[0], "dns64") == 0) { builtin_t *empty; char *server; char *contact; @@ -248,7 +428,10 @@ builtin_create(const char *zone, int argc, char **argv, server = isc_mem_strdup(ns_g_mctx, argv[1]); contact = isc_mem_strdup(ns_g_mctx, argv[2]); if (empty == NULL || server == NULL || contact == NULL) { - *dbdata = &empty_builtin; + if (strcmp(argv[0], "empty") == 0) + *dbdata = &empty_builtin; + else + *dbdata = &dns64_builtin; if (server != NULL) isc_mem_free(ns_g_mctx, server); if (contact != NULL) @@ -256,7 +439,12 @@ builtin_create(const char *zone, int argc, char **argv, if (empty != NULL) isc_mem_put(ns_g_mctx, empty, sizeof (*empty)); } else { - memcpy(empty, &empty_builtin, sizeof (empty_builtin)); + if (strcmp(argv[0], "empty") == 0) + memcpy(empty, &empty_builtin, + sizeof (empty_builtin)); + else + memcpy(empty, &dns64_builtin, + sizeof (empty_builtin)); empty->server = server; empty->contact = contact; *dbdata = empty; @@ -278,7 +466,7 @@ builtin_destroy(const char *zone, void *driverdata, void **dbdata) { */ if (*dbdata == &version_builtin || *dbdata == &hostname_builtin || *dbdata == &authors_builtin || *dbdata == &id_builtin || - *dbdata == &empty_builtin) + *dbdata == &empty_builtin || *dbdata == &dns64_builtin) return; isc_mem_free(ns_g_mctx, b->server); @@ -308,3 +496,4 @@ void ns_builtin_deinit(void) { dns_sdb_unregister(&builtin_impl); } + diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index 93bfa08f44..3f3c2a599f 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + Aug 13, 2004 @@ -288,6 +288,17 @@ options { dnssec-must-be-secure string boolean; dnssec-accept-expired boolean; + dns64-server string; + dns64-contact string; + dns64 prefix { + clients { acl; }; + exclude { acl; }; + mapped { acl; }; + break-dnssec boolean; + recursive-only boolean; + suffix ipv6_address; + }; + empty-server string; empty-contact string; empty-zones-enable boolean; @@ -463,6 +474,17 @@ view string optional_class dnssec-must-be-secure string boolean; dnssec-accept-expired boolean; + dns64-server string; + dns64-contact string; + dns64 prefix { + clients { acl; }; + exclude { acl; }; + mapped { acl; }; + break-dnssec boolean; + recursive-only boolean; + suffix ipv6_address; + }; + empty-server string; empty-contact string; empty-zones-enable boolean; diff --git a/bin/named/server.c b/bin/named/server.c index 5fedf96a35..291c884cd1 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.594 2011/01/07 00:50:06 each Exp $ */ +/* $Id: server.c,v 1.595 2011/01/07 04:31:38 marka Exp $ */ /*! \file */ @@ -1360,6 +1360,83 @@ dlzconfigure_callback(dns_view_t *view, dns_zone_t *zone) { } #endif +static isc_result_t +dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na, + unsigned int prefixlen, const char *server, + const char *contact) +{ + char *cp; + char reverse[48+sizeof("ip6.arpa.")]; + const char *dns64_dbtype[4] = { "_builtin", "dns64", ".", "." }; + const char *sep = ": view "; + const char *viewname = view->name; + const unsigned char *s6; + dns_fixedname_t fixed; + dns_name_t *name; + dns_zone_t *zone = NULL; + int dns64_dbtypec = 4; + isc_buffer_t b; + isc_result_t result; + + REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 || + prefixlen == 56 || prefixlen == 64 || prefixlen == 96); + + if (!strcmp(viewname, "_default")) { + sep = ""; + viewname = ""; + } + + /* + * Construct the reverse name of the zone. + */ + cp = reverse; + s6 = na->type.in6.s6_addr; + while (prefixlen > 0) { + prefixlen -= 8; + sprintf(cp, "%x.%x.", s6[prefixlen/8] & 0xf, + (s6[prefixlen/8] >> 4) & 0xf); + cp += 4; + } + strcat(cp, "ip6.arpa."); + + /* + * Create the actual zone. + */ + if (server != NULL) + dns64_dbtype[2] = server; + if (contact != NULL) + dns64_dbtype[3] = contact; + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + isc_buffer_init(&b, reverse, strlen(reverse)); + isc_buffer_add(&b, strlen(reverse)); + CHECK(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); + CHECK(dns_zone_create(&zone, mctx)); + CHECK(dns_zone_setorigin(zone, name)); + dns_zone_setview(zone, view); + CHECK(dns_zonemgr_managezone(ns_g_server->zonemgr, zone)); + dns_zone_setclass(zone, view->rdclass); + dns_zone_settype(zone, dns_zone_master); + dns_zone_setstats(zone, ns_g_server->zonestats); + CHECK(dns_zone_setdbtype(zone, dns64_dbtypec, dns64_dbtype)); + if (view->queryacl != NULL) + dns_zone_setqueryacl(zone, view->queryacl); + if (view->queryonacl != NULL) + dns_zone_setqueryonacl(zone, view->queryonacl); + dns_zone_setdialup(zone, dns_dialuptype_no); + dns_zone_setnotifytype(zone, dns_notifytype_no); + dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, ISC_TRUE); + CHECK(setquerystats(zone, mctx, ISC_FALSE)); /* XXXMPA */ + CHECK(dns_view_addzone(view, zone)); + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_INFO, "dns64 reverse zone%s%s: %s", sep, + viewname, reverse); + +cleanup: + if (zone != NULL) + dns_zone_detach(&zone); + return (result); +} /* * Configure 'view' according to 'vconfig', taking defaults from 'config' @@ -1707,6 +1784,22 @@ configure_view(dns_view_t *view, cfg_parser_t* parser, const cfg_listelt_t *element; isc_netaddr_t na, suffix, *sp; unsigned int prefixlen; + const char *server, *contact; + const cfg_obj_t *myobj; + + myobj = NULL; + result = ns_config_get(maps, "dns64-server", &myobj); + if (result == ISC_R_SUCCESS) + server = cfg_obj_asstring(myobj); + else + server = NULL; + + myobj = NULL; + result = ns_config_get(maps, "dns64-contact", &myobj); + if (result == ISC_R_SUCCESS) + contact = cfg_obj_asstring(myobj); + else + contact = NULL; for (element = cfg_list_first(obj); element != NULL; @@ -1774,6 +1867,10 @@ configure_view(dns_view_t *view, cfg_parser_t* parser, goto cleanup; dns_dns64_append(&view->dns64, dns64); view->dns64cnt++; + result = dns64_reverse(view, mctx, &na, prefixlen, + server, contact); + if (result != ISC_R_SUCCESS) + goto cleanup; if (clients != NULL) dns_acl_detach(&clients); if (mapped != NULL) diff --git a/bin/tests/system/dns64/ns2/named.conf b/bin/tests/system/dns64/ns2/named.conf index 495025a291..ae5a575974 100644 --- a/bin/tests/system/dns64/ns2/named.conf +++ b/bin/tests/system/dns64/ns2/named.conf @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.2 2010/12/08 02:46:16 marka Exp $ */ +/* $Id: named.conf,v 1.3 2011/01/07 04:31:38 marka Exp $ */ // NS2 @@ -49,6 +49,13 @@ options { suffix ::; }; + dns64-server "dns64.example.net."; + dns64-contact "hostmaster.example.net."; + dns64 2001:32::/32 { clients { 10.53.0.6; }; }; + dns64 2001:40::/40 { clients { 10.53.0.6; }; }; + dns64 2001:48::/48 { clients { 10.53.0.6; }; }; + dns64 2001:56::/56 { clients { 10.53.0.6; }; }; + dns64 2001:64::/64 { clients { 10.53.0.6; }; }; }; zone "." { diff --git a/bin/tests/system/dns64/tests.sh b/bin/tests/system/dns64/tests.sh index 1fedc7d9a8..fde9582b78 100644 --- a/bin/tests/system/dns64/tests.sh +++ b/bin/tests/system/dns64/tests.sh @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.2 2010/12/08 02:46:15 marka Exp $ +# $Id: tests.sh,v 1.3 2011/01/07 04:31:38 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -1244,5 +1244,32 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I: checking reverse mapping ($n)" +ret=0 +$DIG $DIGOPTS -x 2001:aaaa::10.0.0.1 @10.53.0.2 > dig.out.ns2.test$n || ret=1 +grep -i "CNAME.1.0.0.10.IN-ADDR.ARPA.$" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +list=`$DIG $DIGOPTS -b 10.53.0.6 @10.53.0.2 +short aaaa a-only.example | sort` +for a in $list +do + ret=0 + echo "I: checking reverse mapping of $a ($n)" + $DIG $DIGOPTS -x $a @10.53.0.2 > dig.out.ns2.test$n || ret=1 + grep -i "CNAME.5.3.2.1.IN-ADDR.ARPA." dig.out.ns2.test$n > /dev/null || ret=1 + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` +done + +echo "I: checking dns64-server and dns64-contact ($n)" +$DIG $DIGOPTS soa 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.1.0.0.2.ip6.arpa @10.53.0.2 > dig.out.ns2.test$n || ret=1 +grep "SOA.dns64.example.net..hostmaster.example.net." dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:exit status: $status" exit $status diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index cc89a273f7..56f4a9ebe0 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -5142,6 +5142,8 @@ badresp:1,adberr:0,findfail:0,valfail:0] recursion-only yes_or_no; break-dnssec yes_or_no; }; ; + dns64-server name + dns64-contact name preferred-glue ( A | AAAA | NONE ); edns-udp-size number; max-udp-size number; @@ -5763,6 +5765,16 @@ options { Compatible IPv6 prefixes have lengths of 32, 40, 48, 56, 64 and 96 as per RFC 6052. + + Additionally a reverse IP6.ARPA zone will be created for + the prefix to provide a mapping from the IP6.ARPA names + to the corresponding IN-ADDR.ARPA names using synthesized + CNAMEs. dns64-server and + dns64-contact can be used to specify + the name of the server and contact for the zones. These + are settable at the view / options level. These are + not settable on a per-prefix basis. + Each dns64 supports a optional clients acl which defines which clients diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 642de92cb7..2a776f4d79 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.123 2010/12/16 09:51:29 jinmei Exp $ */ +/* $Id: check.c,v 1.124 2011/01/07 04:31:39 marka Exp $ */ /*! \file */ @@ -696,6 +696,12 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) { { "statistics-interval", 60, 28 * 24 * 60 }, /* 28 days */ }; + static const char *server_contact[] = { + "empty-server", "empty-contact", + "dns64-server", "dns64-contact", + NULL + }; + /* * Check that fields specified in units of time other than seconds * have reasonable values. @@ -937,39 +943,30 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) { isc_symtab_destroy(&symtab); } + /* + * Check server/contacts for syntactic validity. + */ + for (i= 0; server_contact[i] != NULL; i++) { + obj = NULL; + (void)cfg_map_get(options, server_contact[i], &obj); + if (obj != NULL) { + str = cfg_obj_asstring(obj); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + tresult = dns_name_fromtext(dns_fixedname_name(&fixed), + &b, dns_rootname, 0, NULL); + if (tresult != ISC_R_SUCCESS) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "%s: invalid name '%s'", + server_contact[i], str); + result = ISC_R_FAILURE; + } + } + } + /* * Check empty zone configuration. */ - obj = NULL; - (void)cfg_map_get(options, "empty-server", &obj); - if (obj != NULL) { - str = cfg_obj_asstring(obj); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, - dns_rootname, 0, NULL); - if (tresult != ISC_R_SUCCESS) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "empty-server: invalid name '%s'", str); - result = ISC_R_FAILURE; - } - } - - obj = NULL; - (void)cfg_map_get(options, "empty-contact", &obj); - if (obj != NULL) { - str = cfg_obj_asstring(obj); - isc_buffer_init(&b, str, strlen(str)); - isc_buffer_add(&b, strlen(str)); - tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b, - dns_rootname, 0, NULL); - if (tresult != ISC_R_SUCCESS) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "empty-contact: invalid name '%s'", str); - result = ISC_R_FAILURE; - } - } - obj = NULL; (void)cfg_map_get(options, "disable-empty-zone", &obj); for (element = cfg_list_first(obj); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 65bb05cf52..66c972bd8a 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.129 2011/01/06 23:24:39 each Exp $ */ +/* $Id: namedconf.c,v 1.130 2011/01/07 04:31:39 marka Exp $ */ /*! \file */ @@ -1090,6 +1090,8 @@ view_clauses[] = { CFG_CLAUSEFLAG_MULTI }, { "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI }, { "dns64", &cfg_type_dns64, CFG_CLAUSEFLAG_MULTI }, + { "dns64-server", &cfg_type_astring, 0 }, + { "dns64-contact", &cfg_type_astring, 0 }, { "dnssec-accept-expired", &cfg_type_boolean, 0 }, { "dnssec-enable", &cfg_type_boolean, 0 }, { "dnssec-lookaside", &cfg_type_lookaside, CFG_CLAUSEFLAG_MULTI },