From c51ef23c2297896a48f0ec947ee2ccc8d82723c5 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 5 Jul 2018 15:29:30 +1000 Subject: [PATCH 1/7] Implement ipv4only.arpa forward and reverse zones as per RFC 8880. --- bin/named/builtin.c | 105 +++++++++++++----- bin/named/named.conf.rst | 6 + bin/named/server.c | 208 +++++++++++++++++++++++++++++++---- doc/man/named.conf.5in | 6 + doc/misc/options | 6 + doc/misc/options.active | 6 + doc/misc/options.grammar.rst | 3 + lib/isccfg/namedconf.c | 3 + 8 files changed, 298 insertions(+), 45 deletions(-) diff --git a/bin/named/builtin.c b/bin/named/builtin.c index 2817ffd3ad..bc6e9b2f1e 100644 --- a/bin/named/builtin.c +++ b/bin/named/builtin.c @@ -32,18 +32,22 @@ typedef struct builtin builtin_t; -static isc_result_t -do_version_lookup(dns_sdblookup_t *lookup); -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); +do_dns64_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); +do_hostname_lookup(dns_sdblookup_t *lookup); +static isc_result_t +do_id_lookup(dns_sdblookup_t *lookup); +static isc_result_t +do_ipv4only_lookup(dns_sdblookup_t *lookup); +static isc_result_t +do_ipv4reverse_lookup(dns_sdblookup_t *lookup); +static isc_result_t +do_version_lookup(dns_sdblookup_t *lookup); /* * We can't use function pointers as the db_data directly @@ -57,12 +61,14 @@ struct builtin { char *contact; }; -static builtin_t version_builtin = { do_version_lookup, NULL, NULL }; -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 builtin_t empty_builtin = { do_empty_lookup, NULL, NULL }; +static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL }; +static builtin_t id_builtin = { do_id_lookup, NULL, NULL }; +static builtin_t ipv4only_builtin = { do_ipv4only_lookup, NULL, NULL }; +static builtin_t ipv4reverse_builtin = { do_ipv4reverse_lookup, NULL, NULL }; +static builtin_t version_builtin = { do_version_lookup, NULL, NULL }; static dns_sdbimplementation_t *builtin_impl; static dns_sdbimplementation_t *dns64_impl; @@ -89,7 +95,8 @@ static const unsigned char hex16[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /*F0*/ }; -const unsigned char decimal[] = "0123456789"; +static const unsigned char decimal[] = "0123456789"; +static const unsigned char ipv4only[] = "\010ipv4only\004arpa"; static size_t dns64_rdata(unsigned char *v, size_t start, unsigned char *rdata) { @@ -429,6 +436,30 @@ do_empty_lookup(dns_sdblookup_t *lookup) { return (ISC_R_SUCCESS); } +static isc_result_t +do_ipv4only_lookup(dns_sdblookup_t *lookup) { + isc_result_t result; + unsigned char data[2][4] = { { 192, 0, 0, 170 }, { 192, 0, 0, 171 } }; + + for (int i = 0; i < 2; i++) { + result = dns_sdb_putrdata(lookup, dns_rdatatype_a, 3600, + data[i], 4); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + return (ISC_R_SUCCESS); +} + +static isc_result_t +do_ipv4reverse_lookup(dns_sdblookup_t *lookup) { + isc_result_t result; + + result = dns_sdb_putrdata(lookup, dns_rdatatype_ptr, 0, ipv4only, + sizeof(ipv4only)); + return (result); +} + static isc_result_t builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) { isc_result_t result; @@ -472,7 +503,10 @@ builtin_create(const char *zone, int argc, char **argv, void *driverdata, UNUSED(zone); UNUSED(driverdata); - if (strcmp(argv[0], "empty") == 0 || strcmp(argv[0], "dns64") == 0) { + if (strcmp(argv[0], "dns64") == 0 || strcmp(argv[0], "empty") == 0 || + strcmp(argv[0], "ipv4only") == 0 || + strcmp(argv[0], "ipv4reverse") == 0) + { if (argc != 3) { return (DNS_R_SYNTAX); } @@ -480,19 +514,27 @@ builtin_create(const char *zone, int argc, char **argv, void *driverdata, return (DNS_R_SYNTAX); } - if (strcmp(argv[0], "version") == 0) { - *dbdata = &version_builtin; + if (strcmp(argv[0], "authors") == 0) { + *dbdata = &authors_builtin; } else if (strcmp(argv[0], "hostname") == 0) { *dbdata = &hostname_builtin; - } else if (strcmp(argv[0], "authors") == 0) { - *dbdata = &authors_builtin; } else if (strcmp(argv[0], "id") == 0) { *dbdata = &id_builtin; - } else if (strcmp(argv[0], "empty") == 0 || - strcmp(argv[0], "dns64") == 0) { + } else if (strcmp(argv[0], "version") == 0) { + *dbdata = &version_builtin; + } else if (strcmp(argv[0], "dns64") == 0 || + strcmp(argv[0], "empty") == 0 || + strcmp(argv[0], "ipv4only") == 0 || + strcmp(argv[0], "ipv4reverse") == 0) + { builtin_t *empty; char *server; char *contact; + + if (argc != 3) { + return (DNS_R_SYNTAX); + } + /* * We don't want built-in zones to fail. Fallback to * the static configuration if memory allocation fails. @@ -501,10 +543,14 @@ builtin_create(const char *zone, int argc, char **argv, void *driverdata, server = isc_mem_strdup(named_g_mctx, argv[1]); contact = isc_mem_strdup(named_g_mctx, argv[2]); if (empty == NULL || server == NULL || contact == NULL) { - if (strcmp(argv[0], "empty") == 0) { - *dbdata = &empty_builtin; - } else { + if (strcmp(argv[0], "dns64") == 0) { *dbdata = &dns64_builtin; + } else if (strcmp(argv[0], "empty") == 0) { + *dbdata = &empty_builtin; + } else if (strcmp(argv[0], "ipv4only") == 0) { + *dbdata = &ipv4only_builtin; + } else { + *dbdata = &ipv4reverse_builtin; } if (server != NULL) { isc_mem_free(named_g_mctx, server); @@ -517,11 +563,17 @@ builtin_create(const char *zone, int argc, char **argv, void *driverdata, sizeof(*empty)); } } else { - if (strcmp(argv[0], "empty") == 0) { + if (strcmp(argv[0], "dns64") == 0) { + memmove(empty, &dns64_builtin, + sizeof(empty_builtin)); + } else if (strcmp(argv[0], "empty") == 0) { memmove(empty, &empty_builtin, sizeof(empty_builtin)); + } else if (strcmp(argv[0], "ipv4only") == 0) { + memmove(empty, &ipv4only_builtin, + sizeof(empty_builtin)); } else { - memmove(empty, &dns64_builtin, + memmove(empty, &ipv4reverse_builtin, sizeof(empty_builtin)); } empty->server = server; @@ -544,9 +596,10 @@ builtin_destroy(const char *zone, void *driverdata, void **dbdata) { /* * Don't free the static versions. */ - if (*dbdata == &version_builtin || *dbdata == &hostname_builtin || - *dbdata == &authors_builtin || *dbdata == &id_builtin || - *dbdata == &empty_builtin || *dbdata == &dns64_builtin) + if (*dbdata == &authors_builtin || *dbdata == &dns64_builtin || + *dbdata == &empty_builtin || *dbdata == &hostname_builtin || + *dbdata == &id_builtin || *dbdata == &ipv4only_builtin || + *dbdata == &ipv4reverse_builtin || *dbdata == &version_builtin) { return; } diff --git a/bin/named/named.conf.rst b/bin/named/named.conf.rst index 1933eefa9c..bf4ba2d059 100644 --- a/bin/named/named.conf.rst +++ b/bin/named/named.conf.rst @@ -264,6 +264,9 @@ OPTIONS hostname ( quoted_string | none ); inline-signing boolean; interface-interval duration; + ipv4only-contact string; + ipv4only-enable boolean; + ipv4only-server string; ixfr-from-differences ( primary | master | secondary | slave | boolean ); keep-response-order { address_match_element; ... }; @@ -640,6 +643,9 @@ VIEW | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; glue-cache boolean;// deprecated inline-signing boolean; + ipv4only-contact string; + ipv4only-enable boolean; + ipv4only-server string; ixfr-from-differences ( primary | master | secondary | slave | boolean ); key string { diff --git a/bin/named/server.c b/bin/named/server.c index 733d2b7f8f..5ce695b5ee 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -150,6 +150,10 @@ #define SIZE_AS_PERCENT ((size_t)-2) #endif /* ifndef SIZE_AS_PERCENT */ +#ifndef ARRAYSIZE +#define ARRAYSIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + #ifdef TUNE_LARGE #define RESOLVER_NTASKS_PERCPU 32 #define UDPBUFFERS 32768 @@ -3386,7 +3390,7 @@ cleanup: } static isc_result_t -create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view, +create_empty_zone(dns_zone_t *pzone, dns_name_t *name, dns_view_t *view, const cfg_obj_t *zonelist, const char **empty_dbtype, int empty_dbtypec, dns_zonestat_level_t statlevel) { char namebuf[DNS_NAME_FORMATSIZE]; @@ -3406,7 +3410,7 @@ create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view, dns_name_t *contact; dns_name_t *ns; dns_name_t *zname; - dns_zone_t *myzone = NULL; + dns_zone_t *zone = NULL; int rbt_dbtypec = 1; isc_result_t result; dns_namereln_t namereln; @@ -3469,7 +3473,7 @@ create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view, /* * Is the existing zone the ok to use? */ - if (zone != NULL) { + if (pzone != NULL) { unsigned int typec; const char **dbargv; @@ -3481,29 +3485,29 @@ create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view, dbargv = empty_dbtype; } - result = check_dbtype(zone, typec, dbargv, view->mctx); + result = check_dbtype(pzone, typec, dbargv, view->mctx); if (result != ISC_R_SUCCESS) { - zone = NULL; + pzone = NULL; } - if (zone != NULL && dns_zone_gettype(zone) != dns_zone_master) { - zone = NULL; + if (pzone != NULL && dns_zone_gettype(pzone) != dns_zone_master) + { + pzone = NULL; } - if (zone != NULL && dns_zone_getfile(zone) != NULL) { - zone = NULL; + if (pzone != NULL && dns_zone_getfile(pzone) != NULL) { + pzone = NULL; } - if (zone != NULL) { - dns_zone_getraw(zone, &myzone); - if (myzone != NULL) { - dns_zone_detach(&myzone); - zone = NULL; + if (pzone != NULL) { + dns_zone_getraw(pzone, &zone); + if (zone != NULL) { + dns_zone_detach(&zone); + pzone = NULL; } } } - if (zone == NULL) { - CHECK(dns_zonemgr_createzone(named_g_server->zonemgr, &myzone)); - zone = myzone; + if (pzone == NULL) { + CHECK(dns_zonemgr_createzone(named_g_server->zonemgr, &zone)); CHECK(dns_zone_setorigin(zone, name)); CHECK(dns_zonemgr_managezone(named_g_server->zonemgr, zone)); if (db == NULL) { @@ -3512,6 +3516,8 @@ create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view, dns_zone_setclass(zone, view->rdclass); dns_zone_settype(zone, dns_zone_master); dns_zone_setstats(zone, named_g_server->zonestats); + } else { + dns_zone_attach(pzone, &zone); } dns_zone_setoption(zone, ~DNS_ZONEOPT_NOCHECKNS, false); @@ -3555,8 +3561,8 @@ create_empty_zone(dns_zone_t *zone, dns_name_t *name, dns_view_t *view, "automatic empty zone%s%s: %s", sep, viewname, namebuf); cleanup: - if (myzone != NULL) { - dns_zone_detach(&myzone); + if (zone != NULL) { + dns_zone_detach(&zone); } if (version != NULL) { dns_db_closeversion(db, &version, false); @@ -3570,6 +3576,84 @@ cleanup: return (result); } +static isc_result_t +create_ipv4only_zone(dns_zone_t *pzone, dns_view_t *view, + const dns_name_t *name, const char *type, isc_mem_t *mctx, + const char *server, const char *contact) { + char namebuf[DNS_NAME_FORMATSIZE]; + const char *dbtype[4] = { "_builtin", NULL, "@", "." }; + const char *sep = ": view "; + const char *viewname = view->name; + dns_zone_t *zone = NULL; + int dbtypec = 4; + isc_result_t result; + + REQUIRE(type != NULL); + + if (!strcmp(viewname, "_default")) { + sep = ""; + viewname = ""; + } + + dbtype[1] = type; + if (server != NULL) { + dbtype[2] = server; + } + if (contact != NULL) { + dbtype[3] = contact; + } + + if (pzone != NULL) { + result = check_dbtype(pzone, dbtypec, dbtype, view->mctx); + if (result != ISC_R_SUCCESS) { + pzone = NULL; + } + } + + if (pzone == NULL) { + /* + * Create the actual zone. + */ + CHECK(dns_zone_create(&zone, mctx)); + CHECK(dns_zone_setorigin(zone, name)); + CHECK(dns_zonemgr_managezone(named_g_server->zonemgr, zone)); + dns_zone_setclass(zone, view->rdclass); + dns_zone_settype(zone, dns_zone_master); + dns_zone_setstats(zone, named_g_server->zonestats); + dns_zone_setdbtype(zone, dbtypec, dbtype); + dns_zone_setdialup(zone, dns_dialuptype_no); + dns_zone_setnotifytype(zone, dns_notifytype_no); + dns_zone_setautomatic(zone, true); + dns_zone_setoption(zone, DNS_ZONEOPT_NOCHECKNS, true); + } else { + dns_zone_attach(pzone, &zone); + } + if (view->queryacl != NULL) { + dns_zone_setqueryacl(zone, view->queryacl); + } else { + dns_zone_clearqueryacl(zone); + } + if (view->queryonacl != NULL) { + dns_zone_setqueryonacl(zone, view->queryonacl); + } else { + dns_zone_clearqueryonacl(zone); + } + dns_zone_setview(zone, view); + CHECK(dns_view_addzone(view, zone)); + + dns_name_format(name, namebuf, sizeof(namebuf)); + isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, + NAMED_LOGMODULE_SERVER, ISC_LOG_INFO, + "automatic ipv4only zone%s%s: %s", sep, viewname, + namebuf); + +cleanup: + if (zone != NULL) { + dns_zone_detach(&zone); + } + return (result); +} + #ifdef HAVE_DNSTAP static isc_result_t configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) { @@ -5629,6 +5713,92 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, } } + obj = NULL; + if (view->rdclass == dns_rdataclass_in) { + (void)named_config_get(maps, "ipv4only-enable", &obj); + } + if (view->rdclass == dns_rdataclass_in && (obj != NULL) + ? cfg_obj_asboolean(obj) + : !ISC_LIST_EMPTY(view->dns64)) + { + const char *server, *contact; + dns_fixedname_t fixed; + dns_name_t *name; + struct { + const char *name; + const char *type; + } zones[] = { + { "ipv4only.arpa", "ipv4only" }, + { "170.0.0.192.in-addr.arpa", "ipv4reverse" }, + { "171.0.0.192.in-addr.arpa", "ipv4reverse" }, + }; + size_t ipv4only_zone; + + obj = NULL; + result = named_config_get(maps, "ipv4only-server", &obj); + if (result == ISC_R_SUCCESS) { + server = cfg_obj_asstring(obj); + } else { + server = NULL; + } + + obj = NULL; + result = named_config_get(maps, "ipv4only-contact", &obj); + if (result == ISC_R_SUCCESS) { + contact = cfg_obj_asstring(obj); + } else { + contact = NULL; + } + + name = dns_fixedname_initname(&fixed); + for (ipv4only_zone = 0; ipv4only_zone < ARRAYSIZE(zones); + ipv4only_zone++) { + dns_forwarders_t *dnsforwarders = NULL; + + CHECK(dns_name_fromstring( + name, zones[ipv4only_zone].name, 0, NULL)); + + (void)dns_view_findzone(view, name, &zone); + if (zone != NULL) { + dns_zone_detach(&zone); + continue; + } + + /* + * If we would forward this name don't add it. + */ + result = dns_fwdtable_find(view->fwdtable, name, NULL, + &dnsforwarders); + if (result == ISC_R_SUCCESS && + dnsforwarders->fwdpolicy == dns_fwdpolicy_only) { + continue; + } + + /* + * See if we can re-use a existing zone. + */ + result = dns_viewlist_find(&named_g_server->viewlist, + view->name, view->rdclass, + &pview); + if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) + { + goto cleanup; + } + + if (pview != NULL) { + (void)dns_view_findzone(pview, name, &zone); + dns_view_detach(&pview); + } + + CHECK(create_ipv4only_zone(zone, view, name, + zones[ipv4only_zone].type, + mctx, server, contact)); + if (zone != NULL) { + dns_zone_detach(&zone); + } + } + } + obj = NULL; result = named_config_get(maps, "rate-limit", &obj); if (result == ISC_R_SUCCESS) { diff --git a/doc/man/named.conf.5in b/doc/man/named.conf.5in index abf620fa11..015763ad19 100644 --- a/doc/man/named.conf.5in +++ b/doc/man/named.conf.5in @@ -327,6 +327,9 @@ options { hostname ( quoted_string | none ); inline\-signing boolean; interface\-interval duration; + ipv4only\-contact string; + ipv4only\-enable boolean; + ipv4only\-server string; ixfr\-from\-differences ( primary | master | secondary | slave | boolean ); keep\-response\-order { address_match_element; ... }; @@ -735,6 +738,9 @@ view string [ class ] { | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; glue\-cache boolean;// deprecated inline\-signing boolean; + ipv4only\-contact string; + ipv4only\-enable boolean; + ipv4only\-server string; ixfr\-from\-differences ( primary | master | secondary | slave | boolean ); key string { diff --git a/doc/misc/options b/doc/misc/options index 27ee95a3d3..eac0be785a 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -215,6 +215,9 @@ options { hostname ( | none ); inline-signing ; interface-interval ; + ipv4only-contact ; + ipv4only-enable ; + ipv4only-server ; ixfr-from-differences ( primary | master | secondary | slave | ); keep-response-order { ; ... }; @@ -589,6 +592,9 @@ view [ ] { | ) [ port ] [ dscp ]; ... }; glue-cache ; // deprecated inline-signing ; + ipv4only-contact ; + ipv4only-enable ; + ipv4only-server ; ixfr-from-differences ( primary | master | secondary | slave | ); key { diff --git a/doc/misc/options.active b/doc/misc/options.active index 9fbffdb840..b418af3c39 100644 --- a/doc/misc/options.active +++ b/doc/misc/options.active @@ -192,6 +192,9 @@ options { hostname ( | none ); inline-signing ; interface-interval ; + ipv4only-contact ; + ipv4only-enable ; + ipv4only-server ; ixfr-from-differences ( primary | master | secondary | slave | ); keep-response-order { ; ... }; @@ -529,6 +532,9 @@ view [ ] { | ) [ port ] [ dscp ]; ... }; glue-cache ; // deprecated inline-signing ; + ipv4only-contact ; + ipv4only-enable ; + ipv4only-server ; ixfr-from-differences ( primary | master | secondary | slave | ); key { diff --git a/doc/misc/options.grammar.rst b/doc/misc/options.grammar.rst index ace29b5704..9dba4f965a 100644 --- a/doc/misc/options.grammar.rst +++ b/doc/misc/options.grammar.rst @@ -120,6 +120,9 @@ hostname ( | none ); inline-signing ; interface-interval ; + ipv4only-contact ; + ipv4only-enable ; + ipv4only-server ; ixfr-from-differences ( primary | master | secondary | slave | ); keep-response-order { ; ... }; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index f139aa3dda..ceb9a02229 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -2022,6 +2022,9 @@ static cfg_clausedef_t view_clauses[] = { { "filter-aaaa-on-v4", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "filter-aaaa-on-v6", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, { "glue-cache", &cfg_type_boolean, CFG_CLAUSEFLAG_DEPRECATED }, + { "ipv4only-enable", &cfg_type_boolean, 0 }, + { "ipv4only-contact", &cfg_type_astring, 0 }, + { "ipv4only-server", &cfg_type_astring, 0 }, { "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 }, { "lame-ttl", &cfg_type_duration, 0 }, #ifdef HAVE_LMDB From cdfe66032656d90af8ccb8d54216e2409e39b0e7 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 5 Jul 2018 16:45:05 +1000 Subject: [PATCH 2/7] Checking synthesis of AAAA of builtin ipv4only.arpa --- bin/tests/system/dns64/tests.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bin/tests/system/dns64/tests.sh b/bin/tests/system/dns64/tests.sh index 753de1f2aa..f3b60d0ea3 100644 --- a/bin/tests/system/dns64/tests.sh +++ b/bin/tests/system/dns64/tests.sh @@ -1429,5 +1429,14 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +echo_i "checking synthesis of AAAA from builtin ipv4only.arpa ($n)" +ret=0 +$DIG $DIGOPTS aaaa ipv4only.arpa -b 10.53.0.7 @10.53.0.2 > dig.out.ns2.test$n || ret=1 +grep -i 'ipv4only.arpa.*IN.AAAA.2001:96::c000:aa' dig.out.ns2.test$n >/dev/null || ret=1 +grep -i 'ipv4only.arpa.*IN.AAAA.2001:96::c000:ab' 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" [ $status -eq 0 ] || exit 1 From 5684c21bcf4fa4c5dad491a8f6874cc2cc20ff6f Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 1 Sep 2020 12:03:59 +1000 Subject: [PATCH 3/7] Generate PTR records for DNS64 mapped ipv4only.arpa reverses. Rather than generating CNAMES records pointing into IN-ADDR.ARPA, generate PTR records directly as the names are known as per RFC 8880. --- bin/named/builtin.c | 12 +++++++++++- bin/tests/system/dns64/tests.sh | 10 ++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/bin/named/builtin.c b/bin/named/builtin.c index bc6e9b2f1e..c2bbc59655 100644 --- a/bin/named/builtin.c +++ b/bin/named/builtin.c @@ -296,6 +296,16 @@ dns64_cname(const dns_name_t *zone, const dns_name_t *name, */ return (ISC_R_NOTFOUND); } + + /* + * Reverse of 192.0.0.170 or 192.0.0.171 maps to ipv4only.arpa. + */ + if ((v[0] == 170 || v[0] == 171) && v[1] == 0 && v[2] == 0 && + v[3] == 192) { + return (dns_sdb_putrdata(lookup, dns_rdatatype_ptr, 3600, + ipv4only, sizeof(ipv4only))); + } + return (dns_sdb_putrdata(lookup, dns_rdatatype_cname, 600, rdata, (unsigned int)len)); } @@ -455,7 +465,7 @@ static isc_result_t do_ipv4reverse_lookup(dns_sdblookup_t *lookup) { isc_result_t result; - result = dns_sdb_putrdata(lookup, dns_rdatatype_ptr, 0, ipv4only, + result = dns_sdb_putrdata(lookup, dns_rdatatype_ptr, 3600, ipv4only, sizeof(ipv4only)); return (result); } diff --git a/bin/tests/system/dns64/tests.sh b/bin/tests/system/dns64/tests.sh index f3b60d0ea3..bf0ca7a51f 100644 --- a/bin/tests/system/dns64/tests.sh +++ b/bin/tests/system/dns64/tests.sh @@ -1438,5 +1438,15 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +echo_i "checking reverse of dns64 mapped ipv4only.arpa addresses returns ipv4only.arpa ($n)" +ret=0 +$DIG $DIGOPTS ptr -x 2001:96::192.0.0.170 -b 10.53.0.7 @10.53.0.2 > dig.out.170.ns2.test$n || ret=1 +$DIG $DIGOPTS ptr -x 2001:96::192.0.0.171 -b 10.53.0.7 @10.53.0.2 > dig.out.171.ns2.test$n || ret=1 +grep "ip6\.arpa\..*PTR.*ipv4only\.arpa\." dig.out.170.ns2.test$n >/dev/null || ret=1 +grep "ip6\.arpa\..*PTR.*ipv4only\.arpa\." dig.out.171.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" [ $status -eq 0 ] || exit 1 From 64c45abab267eb821c3ea49c1518767d7654fac3 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 11 Jul 2018 12:18:27 +1000 Subject: [PATCH 4/7] Document ipv4only-enable, ipv4only-contact and ipv4only-server. --- doc/arm/reference.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 726f37ed5a..0790cff7f5 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -1365,6 +1365,9 @@ default is used. contact for the zones. These can be set at the view/options level but not on a per-prefix basis. + ``dns64`` will also cause IPV4ONLY.ARPA to be created if not + explicitly disabled using ``ipv4only-enable``. + Each ``dns64`` supports an optional ``clients`` ACL that determines which clients are affected by this directive. If not defined, it defaults to ``any;``. @@ -1659,6 +1662,12 @@ Boolean Options This option was part of an experimental implementation of the EDNS CLIENT-SUBNET for authoritative servers, but is now obsolete. +``ipv4only-enable`` + Create the IPV4ONLY.ARPA zone as described in RFC 8880. By + default the zone is only created if a DNS64 prefix is configured. + Control the SOA contact and server values with ``ipv4only-contact`` + and ``ipv4only-server`` respectively. + ``root-key-sentinel`` If ``yes``, respond to root key sentinel probes as described in draft-ietf-dnsop-kskroll-sentinel-08. The default is ``yes``. From 6d10a57397c2fb15234d546deee4736b3fec7435 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 9 Dec 2020 09:47:48 +1100 Subject: [PATCH 5/7] Add RFC 7050 and RFC 8880 to rfc-compliance --- doc/misc/rfc-compliance | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/misc/rfc-compliance b/doc/misc/rfc-compliance index e7cada0257..07e9735377 100644 --- a/doc/misc/rfc-compliance +++ b/doc/misc/rfc-compliance @@ -90,6 +90,7 @@ or Best Current Practice (BCP) documents. The list is non exhaustive. RFC6891 RFC6944 RFC7043 + RFC7050 [21] RFC7314 RFC7344 [20] RFC7477 @@ -98,6 +99,7 @@ or Best Current Practice (BCP) documents. The list is non exhaustive. RFC7830 [15] RFC7929 RFC8080 + RFC8880 No longer supported @@ -182,3 +184,5 @@ to the experimental category by RFC3363. [19] RSAMD5 support has been removed. See RFC 6944. [20] Updating of parent zones is not yet implemented. + +[21] RFC 7050 is updated by RFC 8880 From 88943974dec9f8c6c4c1e3d2ece23528a6b4f920 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 1 Sep 2020 10:32:44 +1000 Subject: [PATCH 6/7] Add release note entry --- doc/notes/notes-current.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index b06d0e4ada..1694e20d4c 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -55,6 +55,8 @@ Feature Changes needs to be changed when operator wants to change the default EDNS buffer size. [GL #2250] +- ``ipv4only.arpa`` is now served when ``dns64`` is configured. [GL #385] + Bug Fixes ~~~~~~~~~ From ea0dbb53389065fe57bca35b70b6066a865b1170 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 1 Sep 2020 10:30:45 +1000 Subject: [PATCH 7/7] Add CHANGES note --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 0a6e5bd128..af8560d335 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +5549. [protocol] Serve ipv4only.arpa when dns64 is configured. [GL #385] + 5548. [placeholder] 5547. [placeholder]