mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
2981. [func] Partial DNS64 support (AAAA synthesis). [RT #21991]
This commit is contained in:
parent
b59e6107bf
commit
e334405421
24 changed files with 2914 additions and 49 deletions
2
CHANGES
2
CHANGES
|
|
@ -1,3 +1,5 @@
|
|||
2981. [func] Partial DNS64 support (AAAA synthesis). [RT #21991]
|
||||
|
||||
2980. [bug] named didn't properly handle UPDATES that changed the
|
||||
TTL of the NSEC3PARAM RRset. [RT #22363]
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.h,v 1.42 2010/09/24 08:31:23 tbox Exp $ */
|
||||
/* $Id: query.h,v 1.43 2010/12/08 02:46:15 marka Exp $ */
|
||||
|
||||
#ifndef NAMED_QUERY_H
|
||||
#define NAMED_QUERY_H 1
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
#include <isc/netaddr.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
#include <dns/rdataset.h>
|
||||
|
||||
#include <named/types.h>
|
||||
|
||||
|
|
@ -57,6 +58,12 @@ struct ns_query {
|
|||
isc_bufferlist_t namebufs;
|
||||
ISC_LIST(ns_dbversion_t) activeversions;
|
||||
ISC_LIST(ns_dbversion_t) freeversions;
|
||||
dns_rdataset_t * dns64_aaaa;
|
||||
dns_rdataset_t * dns64_sigaaaa;
|
||||
isc_boolean_t * dns64_aaaaok;
|
||||
unsigned int dns64_aaaaoklen;
|
||||
unsigned int dns64_options;
|
||||
unsigned int dns64_ttl;
|
||||
};
|
||||
|
||||
#define NS_QUERYATTR_RECURSIONOK 0x0001
|
||||
|
|
@ -73,6 +80,9 @@ struct ns_query {
|
|||
#define NS_QUERYATTR_NOADDITIONAL 0x0800
|
||||
#define NS_QUERYATTR_CACHEACLOKVALID 0x1000
|
||||
#define NS_QUERYATTR_CACHEACLOK 0x2000
|
||||
#define NS_QUERYATTR_DNS64 0x4000
|
||||
#define NS_QUERYATTR_DNS64EXCLUDE 0x8000
|
||||
|
||||
|
||||
isc_result_t
|
||||
ns_query_init(ns_client_t *client);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.c,v 1.346 2010/09/24 05:09:02 marka Exp $ */
|
||||
/* $Id: query.c,v 1.347 2010/12/08 02:46:15 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
#ifdef DLZ
|
||||
#include <dns/dlz.h>
|
||||
#endif
|
||||
#include <dns/dns64.h>
|
||||
#include <dns/dnssec.h>
|
||||
#include <dns/events.h>
|
||||
#include <dns/message.h>
|
||||
|
|
@ -62,6 +63,17 @@
|
|||
#include <named/sortlist.h>
|
||||
#include <named/xfrout.h>
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* It has been recommended that DNS64 be changed to return excluded
|
||||
* AAAA addresses if DNS64 synthesis does not occur. This minimises
|
||||
* the impact on the lookup results. While most DNS AAAA lookups are
|
||||
* done to send IP packets to a host, not all of them are and filtering
|
||||
* excluded addresses has a negative impact on those uses.
|
||||
*/
|
||||
#define dns64_bis_return_excluded_addresses 1
|
||||
#endif
|
||||
|
||||
/*% Partial answer? */
|
||||
#define PARTIALANSWER(c) (((c)->query.attributes & \
|
||||
NS_QUERYATTR_PARTIALANSWER) != 0)
|
||||
|
|
@ -92,6 +104,12 @@
|
|||
/*% Secure? */
|
||||
#define SECURE(c) (((c)->query.attributes & \
|
||||
NS_QUERYATTR_SECURE) != 0)
|
||||
/*% DNS64 A lookup? */
|
||||
#define DNS64(c) (((c)->query.attributes & \
|
||||
NS_QUERYATTR_DNS64) != 0)
|
||||
|
||||
#define DNS64EXCLUDE(c) (((c)->query.attributes & \
|
||||
NS_QUERYATTR_DNS64EXCLUDE) != 0)
|
||||
|
||||
/*% No QNAME Proof? */
|
||||
#define NOQNAME(r) (((r)->attributes & \
|
||||
|
|
@ -251,6 +269,19 @@ ns_query_cancel(ns_client_t *client) {
|
|||
UNLOCK(&client->query.fetchlock);
|
||||
}
|
||||
|
||||
static inline void
|
||||
query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
|
||||
dns_rdataset_t *rdataset = *rdatasetp;
|
||||
|
||||
CTRACE("query_putrdataset");
|
||||
if (rdataset != NULL) {
|
||||
if (dns_rdataset_isassociated(rdataset))
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
dns_message_puttemprdataset(client->message, rdatasetp);
|
||||
}
|
||||
CTRACE("query_putrdataset: done");
|
||||
}
|
||||
|
||||
static inline void
|
||||
query_reset(ns_client_t *client, isc_boolean_t everything) {
|
||||
isc_buffer_t *dbuf, *dbuf_next;
|
||||
|
|
@ -285,6 +316,18 @@ query_reset(ns_client_t *client, isc_boolean_t everything) {
|
|||
if (client->query.authzone != NULL)
|
||||
dns_zone_detach(&client->query.authzone);
|
||||
|
||||
if (client->query.dns64_aaaa != NULL)
|
||||
query_putrdataset(client, &client->query.dns64_aaaa);
|
||||
if (client->query.dns64_sigaaaa != NULL)
|
||||
query_putrdataset(client, &client->query.dns64_sigaaaa);
|
||||
if (client->query.dns64_aaaaok != NULL) {
|
||||
isc_mem_put(client->mctx, client->query.dns64_aaaaok,
|
||||
client->query.dns64_aaaaoklen *
|
||||
sizeof(isc_boolean_t));
|
||||
client->query.dns64_aaaaok = NULL;
|
||||
client->query.dns64_aaaaoklen = 0;
|
||||
}
|
||||
|
||||
query_freefreeversions(client, everything);
|
||||
|
||||
for (dbuf = ISC_LIST_HEAD(client->query.namebufs);
|
||||
|
|
@ -311,12 +354,13 @@ query_reset(ns_client_t *client, isc_boolean_t everything) {
|
|||
client->query.restarts = 0;
|
||||
client->query.timerset = ISC_FALSE;
|
||||
client->query.origqname = NULL;
|
||||
client->query.qname = NULL;
|
||||
client->query.dboptions = 0;
|
||||
client->query.fetchoptions = 0;
|
||||
client->query.gluedb = NULL;
|
||||
client->query.authdbset = ISC_FALSE;
|
||||
client->query.isreferral = ISC_FALSE;
|
||||
client->query.dns64_options = 0;
|
||||
client->query.dns64_ttl = ISC_UINT32_MAX;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -473,20 +517,6 @@ query_newrdataset(ns_client_t *client) {
|
|||
return (rdataset);
|
||||
}
|
||||
|
||||
static inline void
|
||||
query_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
|
||||
dns_rdataset_t *rdataset = *rdatasetp;
|
||||
|
||||
CTRACE("query_putrdataset");
|
||||
if (rdataset != NULL) {
|
||||
if (dns_rdataset_isassociated(rdataset))
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
dns_message_puttemprdataset(client->message, rdatasetp);
|
||||
}
|
||||
CTRACE("query_putrdataset: done");
|
||||
}
|
||||
|
||||
|
||||
static inline isc_result_t
|
||||
query_newdbversion(ns_client_t *client, unsigned int n) {
|
||||
unsigned int i;
|
||||
|
|
@ -549,6 +579,10 @@ ns_query_init(ns_client_t *client) {
|
|||
client->query.authzone = NULL;
|
||||
client->query.authdbset = ISC_FALSE;
|
||||
client->query.isreferral = ISC_FALSE;
|
||||
client->query.dns64_aaaa = NULL;
|
||||
client->query.dns64_sigaaaa = NULL;
|
||||
client->query.dns64_aaaaok = NULL;
|
||||
client->query.dns64_aaaaoklen = 0;
|
||||
query_reset(client, ISC_FALSE);
|
||||
result = query_newdbversion(client, 3);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -1958,6 +1992,323 @@ query_addrdataset(ns_client_t *client, dns_name_t *fname,
|
|||
CTRACE("query_addrdataset: done");
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
query_dns64(ns_client_t *client, dns_name_t **namep, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset, isc_buffer_t *dbuf,
|
||||
dns_section_t section)
|
||||
{
|
||||
dns_name_t *name, *mname;
|
||||
dns_rdata_t *dns64_rdata;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdatalist_t *dns64_rdatalist;
|
||||
dns_rdataset_t *dns64_rdataset;
|
||||
dns_rdataset_t *mrdataset;
|
||||
isc_buffer_t *buffer;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
dns_view_t *view = client->view;
|
||||
isc_netaddr_t netaddr;
|
||||
dns_dns64_t *dns64;
|
||||
unsigned int flags = 0;
|
||||
|
||||
/*%
|
||||
* To the current response for 'client', add the answer RRset
|
||||
* '*rdatasetp' and an optional signature set '*sigrdatasetp', with
|
||||
* owner name '*namep', to section 'section', unless they are
|
||||
* already there. Also add any pertinent additional data.
|
||||
*
|
||||
* If 'dbuf' is not NULL, then '*namep' is the name whose data is
|
||||
* stored in 'dbuf'. In this case, query_addrrset() guarantees that
|
||||
* when it returns the name will either have been kept or released.
|
||||
*/
|
||||
CTRACE("query_dns64");
|
||||
name = *namep;
|
||||
mname = NULL;
|
||||
mrdataset = NULL;
|
||||
buffer = NULL;
|
||||
dns64_rdata = NULL;
|
||||
dns64_rdataset = NULL;
|
||||
dns64_rdatalist = NULL;
|
||||
result = dns_message_findname(client->message, section,
|
||||
name, dns_rdatatype_aaaa,
|
||||
rdataset->covers,
|
||||
&mname, &mrdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* We've already got an RRset of the given name and type.
|
||||
* There's nothing else to do;
|
||||
*/
|
||||
CTRACE("query_dns64: dns_message_findname succeeded: done");
|
||||
if (dbuf != NULL)
|
||||
query_releasename(client, namep);
|
||||
return (ISC_R_SUCCESS);
|
||||
} else if (result == DNS_R_NXDOMAIN) {
|
||||
/*
|
||||
* The name doesn't exist.
|
||||
*/
|
||||
if (dbuf != NULL)
|
||||
query_keepname(client, name, dbuf);
|
||||
dns_message_addname(client->message, name, section);
|
||||
*namep = NULL;
|
||||
mname = name;
|
||||
} else {
|
||||
RUNTIME_CHECK(result == DNS_R_NXRRSET);
|
||||
if (dbuf != NULL)
|
||||
query_releasename(client, namep);
|
||||
}
|
||||
|
||||
if (rdataset->trust != dns_trust_secure &&
|
||||
(section == DNS_SECTION_ANSWER ||
|
||||
section == DNS_SECTION_AUTHORITY))
|
||||
client->query.attributes &= ~NS_QUERYATTR_SECURE;
|
||||
|
||||
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
||||
|
||||
result = isc_buffer_allocate(client->mctx, &buffer, view->dns64cnt *
|
||||
16 * dns_rdataset_count(rdataset));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = dns_message_gettemprdataset(client->message, &dns64_rdataset);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = dns_message_gettemprdatalist(client->message,
|
||||
&dns64_rdatalist);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
dns_rdataset_init(dns64_rdataset);
|
||||
dns_rdatalist_init(dns64_rdatalist);
|
||||
dns64_rdatalist->rdclass = dns_rdataclass_in;
|
||||
dns64_rdatalist->type = dns_rdatatype_aaaa;
|
||||
if (client->query.dns64_ttl != ISC_UINT32_MAX)
|
||||
dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl,
|
||||
client->query.dns64_ttl);
|
||||
else
|
||||
dns64_rdatalist->ttl = ISC_MIN(rdataset->ttl, 600);
|
||||
|
||||
if (RECURSIONOK(client))
|
||||
flags |= DNS_DNS64_RECURSIVE;
|
||||
|
||||
/*
|
||||
* We use the signatures from the A lookup to set DNS_DNS64_DNSSEC
|
||||
* as this provides a easy way to see if the answer was signed.
|
||||
*/
|
||||
if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
|
||||
flags |= DNS_DNS64_DNSSEC;
|
||||
|
||||
for (result = dns_rdataset_first(rdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(rdataset)) {
|
||||
for (dns64 = ISC_LIST_HEAD(client->view->dns64);
|
||||
dns64 != NULL; dns64 = dns_dns64_next(dns64)) {
|
||||
|
||||
dns_rdataset_current(rdataset, &rdata);
|
||||
isc__buffer_availableregion(buffer, &r);
|
||||
INSIST(r.length >= 16);
|
||||
result = dns_dns64_aaaafroma(dns64, &netaddr,
|
||||
client->signer,
|
||||
&ns_g_server->aclenv,
|
||||
flags, rdata.data, r.base);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_rdata_reset(&rdata);
|
||||
continue;
|
||||
}
|
||||
isc_buffer_add(buffer, 16);
|
||||
isc_buffer_remainingregion(buffer, &r);
|
||||
isc_buffer_forward(buffer, 16);
|
||||
result = dns_message_gettemprdata(client->message,
|
||||
&dns64_rdata);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
dns_rdata_init(dns64_rdata);
|
||||
dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
|
||||
dns_rdatatype_aaaa, &r);
|
||||
ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata,
|
||||
link);
|
||||
dns64_rdata = NULL;
|
||||
dns_rdata_reset(&rdata);
|
||||
}
|
||||
}
|
||||
if (result != ISC_R_NOMORE)
|
||||
goto cleanup;
|
||||
|
||||
if (ISC_LIST_EMPTY(dns64_rdatalist->rdata))
|
||||
goto cleanup;
|
||||
|
||||
result = dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
|
||||
dns64_rdataset->trust = rdataset->trust;
|
||||
query_addrdataset(client, mname, dns64_rdataset);
|
||||
dns64_rdataset = NULL;
|
||||
dns64_rdatalist = NULL;
|
||||
dns_message_takebuffer(client->message, &buffer);
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (buffer != NULL)
|
||||
isc_buffer_free(&buffer);
|
||||
|
||||
if (dns64_rdata != NULL)
|
||||
dns_message_puttemprdata(client->message, &dns64_rdata);
|
||||
|
||||
if (dns64_rdataset != NULL)
|
||||
dns_message_puttemprdataset(client->message, &dns64_rdataset);
|
||||
|
||||
if (dns64_rdatalist != NULL) {
|
||||
for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata);
|
||||
dns64_rdata != NULL;
|
||||
dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata))
|
||||
{
|
||||
ISC_LIST_UNLINK(dns64_rdatalist->rdata,
|
||||
dns64_rdata, link);
|
||||
dns_message_puttemprdata(client->message, &dns64_rdata);
|
||||
}
|
||||
dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
|
||||
}
|
||||
|
||||
CTRACE("query_dns64: done");
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
query_filter64(ns_client_t *client, dns_name_t **namep,
|
||||
dns_rdataset_t *rdataset, isc_buffer_t *dbuf,
|
||||
dns_section_t section)
|
||||
{
|
||||
dns_name_t *name, *mname;
|
||||
dns_rdata_t *myrdata;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdatalist_t *myrdatalist;
|
||||
dns_rdataset_t *myrdataset;
|
||||
isc_buffer_t *buffer;
|
||||
isc_region_t r;
|
||||
isc_result_t result;
|
||||
unsigned int i;
|
||||
|
||||
CTRACE("query_filter64");
|
||||
|
||||
INSIST(client->query.dns64_aaaaok != NULL);
|
||||
INSIST(client->query.dns64_aaaaoklen == dns_rdataset_count(rdataset));
|
||||
|
||||
name = *namep;
|
||||
mname = NULL;
|
||||
buffer = NULL;
|
||||
myrdata = NULL;
|
||||
myrdataset = NULL;
|
||||
myrdatalist = NULL;
|
||||
result = dns_message_findname(client->message, section,
|
||||
name, dns_rdatatype_aaaa,
|
||||
rdataset->covers,
|
||||
&mname, &myrdataset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* We've already got an RRset of the given name and type.
|
||||
* There's nothing else to do;
|
||||
*/
|
||||
CTRACE("query_filter64: dns_message_findname succeeded: done");
|
||||
if (dbuf != NULL)
|
||||
query_releasename(client, namep);
|
||||
return;
|
||||
} else if (result == DNS_R_NXDOMAIN) {
|
||||
mname = name;
|
||||
*namep = NULL;
|
||||
} else {
|
||||
RUNTIME_CHECK(result == DNS_R_NXRRSET);
|
||||
if (dbuf != NULL)
|
||||
query_releasename(client, namep);
|
||||
dbuf = NULL;
|
||||
}
|
||||
|
||||
if (rdataset->trust != dns_trust_secure &&
|
||||
(section == DNS_SECTION_ANSWER ||
|
||||
section == DNS_SECTION_AUTHORITY))
|
||||
client->query.attributes &= ~NS_QUERYATTR_SECURE;
|
||||
|
||||
result = isc_buffer_allocate(client->mctx, &buffer,
|
||||
16 * dns_rdataset_count(rdataset));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = dns_message_gettemprdataset(client->message, &myrdataset);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
result = dns_message_gettemprdatalist(client->message, &myrdatalist);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
dns_rdataset_init(myrdataset);
|
||||
dns_rdatalist_init(myrdatalist);
|
||||
myrdatalist->rdclass = dns_rdataclass_in;
|
||||
myrdatalist->type = dns_rdatatype_aaaa;
|
||||
myrdatalist->ttl = rdataset->ttl;
|
||||
|
||||
i = 0;
|
||||
for (result = dns_rdataset_first(rdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(rdataset)) {
|
||||
if (!client->query.dns64_aaaaok[i++])
|
||||
continue;
|
||||
dns_rdataset_current(rdataset, &rdata);
|
||||
INSIST(rdata.length == 16);
|
||||
isc_buffer_putmem(buffer, rdata.data, rdata.length);
|
||||
isc_buffer_remainingregion(buffer, &r);
|
||||
isc_buffer_forward(buffer, rdata.length);
|
||||
result = dns_message_gettemprdata(client->message, &myrdata);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
dns_rdata_init(myrdata);
|
||||
dns_rdata_fromregion(myrdata, dns_rdataclass_in,
|
||||
dns_rdatatype_aaaa, &r);
|
||||
ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link);
|
||||
myrdata = NULL;
|
||||
dns_rdata_reset(&rdata);
|
||||
}
|
||||
if (result != ISC_R_NOMORE)
|
||||
goto cleanup;
|
||||
|
||||
result = dns_rdatalist_tordataset(myrdatalist, myrdataset);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
|
||||
if (mname == name) {
|
||||
if (dbuf != NULL)
|
||||
query_keepname(client, name, dbuf);
|
||||
dns_message_addname(client->message, name, section);
|
||||
dbuf = NULL;
|
||||
}
|
||||
myrdataset->trust = rdataset->trust;
|
||||
query_addrdataset(client, mname, myrdataset);
|
||||
myrdataset = NULL;
|
||||
myrdatalist = NULL;
|
||||
dns_message_takebuffer(client->message, &buffer);
|
||||
|
||||
cleanup:
|
||||
if (buffer != NULL)
|
||||
isc_buffer_free(&buffer);
|
||||
|
||||
if (myrdata != NULL)
|
||||
dns_message_puttemprdata(client->message, &myrdata);
|
||||
|
||||
if (myrdataset != NULL)
|
||||
dns_message_puttemprdataset(client->message, &myrdataset);
|
||||
|
||||
if (myrdatalist != NULL) {
|
||||
for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata);
|
||||
myrdata != NULL;
|
||||
myrdata = ISC_LIST_HEAD(myrdatalist->rdata))
|
||||
{
|
||||
ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link);
|
||||
dns_message_puttemprdata(client->message, &myrdata);
|
||||
}
|
||||
dns_message_puttemprdatalist(client->message, &myrdatalist);
|
||||
}
|
||||
if (dbuf != NULL)
|
||||
query_releasename(client, &name);
|
||||
|
||||
CTRACE("query_filter64: done");
|
||||
}
|
||||
|
||||
static void
|
||||
query_addrrset(ns_client_t *client, dns_name_t **namep,
|
||||
dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp,
|
||||
|
|
@ -2036,7 +2387,7 @@ query_addrrset(ns_client_t *client, dns_name_t **namep,
|
|||
|
||||
static inline isc_result_t
|
||||
query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
|
||||
isc_boolean_t zero_ttl, isc_boolean_t isassociated)
|
||||
unsigned int override_ttl, isc_boolean_t isassociated)
|
||||
{
|
||||
dns_name_t *name;
|
||||
dns_dbnode_t *node;
|
||||
|
|
@ -2119,10 +2470,11 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
|
|||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
|
||||
if (zero_ttl) {
|
||||
rdataset->ttl = 0;
|
||||
if (override_ttl != ISC_UINT32_MAX &&
|
||||
override_ttl < rdataset->ttl) {
|
||||
rdataset->ttl = override_ttl;
|
||||
if (sigrdataset != NULL)
|
||||
sigrdataset->ttl = 0;
|
||||
sigrdataset->ttl = override_ttl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3718,6 +4070,53 @@ is_v4_client(ns_client_t *client) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static isc_boolean_t
|
||||
dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset,
|
||||
dns_rdataset_t *sigrdataset)
|
||||
{
|
||||
isc_netaddr_t netaddr;
|
||||
dns_dns64_t *dns64 = ISC_LIST_HEAD(client->view->dns64);
|
||||
unsigned int flags = 0;
|
||||
unsigned int i, count;
|
||||
isc_boolean_t *aaaaok;
|
||||
|
||||
INSIST(client->query.dns64_aaaaok == NULL);
|
||||
INSIST(client->query.dns64_aaaaoklen == 0);
|
||||
INSIST(client->query.dns64_aaaa == NULL);
|
||||
INSIST(client->query.dns64_sigaaaa == NULL);
|
||||
|
||||
if (dns64 == NULL)
|
||||
return (ISC_TRUE);
|
||||
|
||||
if (RECURSIONOK(client))
|
||||
flags |= DNS_DNS64_RECURSIVE;
|
||||
|
||||
if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset))
|
||||
flags |= DNS_DNS64_DNSSEC;
|
||||
|
||||
count = dns_rdataset_count(rdataset);
|
||||
aaaaok = isc_mem_get(client->mctx, sizeof(isc_boolean_t) * count);
|
||||
|
||||
isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
|
||||
if (dns_dns64_aaaaok(dns64, &netaddr, client->signer,
|
||||
&ns_g_server->aclenv, flags, rdataset,
|
||||
aaaaok, count)) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (aaaaok != NULL && !aaaaok[i]) {
|
||||
client->query.dns64_aaaaok = aaaaok;
|
||||
client->query.dns64_aaaaoklen = count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == count)
|
||||
isc_mem_put(client->mctx, aaaaok,
|
||||
sizeof(isc_boolean_t) * count);
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
isc_mem_put(client->mctx, aaaaok, sizeof(isc_boolean_t) * count);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the bulk of query processing for the current query of 'client'.
|
||||
* If 'event' is non-NULL, we are returning from recursion and 'qtype'
|
||||
|
|
@ -3753,6 +4152,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
dns_rdataset_t *noqname;
|
||||
isc_boolean_t resuming;
|
||||
int line = -1;
|
||||
isc_boolean_t dns64_exclude, dns64;
|
||||
|
||||
CTRACE("query_find");
|
||||
|
||||
|
|
@ -3778,6 +4178,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
zone = NULL;
|
||||
need_wildcardproof = ISC_FALSE;
|
||||
empty_wild = ISC_FALSE;
|
||||
dns64_exclude = dns64 = ISC_FALSE;
|
||||
options = 0;
|
||||
resuming = ISC_FALSE;
|
||||
is_zone = ISC_FALSE;
|
||||
|
|
@ -3787,7 +4188,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
* We're returning from recursion. Restore the query context
|
||||
* and resume.
|
||||
*/
|
||||
|
||||
want_restart = ISC_FALSE;
|
||||
authoritative = ISC_FALSE;
|
||||
|
||||
|
|
@ -3800,6 +4200,14 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
node = event->node;
|
||||
rdataset = event->rdataset;
|
||||
sigrdataset = event->sigrdataset;
|
||||
if (DNS64(client)) {
|
||||
client->query.attributes &= ~NS_QUERYATTR_DNS64;
|
||||
dns64 = ISC_TRUE;
|
||||
}
|
||||
if (DNS64EXCLUDE(client)) {
|
||||
client->query.attributes &= ~NS_QUERYATTR_DNS64EXCLUDE;
|
||||
dns64_exclude = ISC_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* We'll need some resources...
|
||||
|
|
@ -3823,7 +4231,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
|
||||
result = event->result;
|
||||
resuming = ISC_TRUE;
|
||||
|
||||
goto resume;
|
||||
}
|
||||
|
||||
|
|
@ -4029,10 +4436,16 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
if (RECURSIONOK(client)) {
|
||||
result = query_recurse(client, qtype,
|
||||
NULL, NULL, resuming);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
client->query.attributes |=
|
||||
NS_QUERYATTR_RECURSING;
|
||||
else
|
||||
if (dns64)
|
||||
client->query.attributes |=
|
||||
NS_QUERYATTR_DNS64;
|
||||
if (dns64_exclude)
|
||||
client->query.attributes |=
|
||||
NS_QUERYATTR_DNS64EXCLUDE;
|
||||
} else
|
||||
RECURSE_ERROR(result);
|
||||
goto cleanup;
|
||||
} else {
|
||||
|
|
@ -4205,13 +4618,28 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
result = query_recurse(client, qtype,
|
||||
NULL, NULL,
|
||||
resuming);
|
||||
else if (dns64)
|
||||
result = query_recurse(client,
|
||||
dns_rdatatype_a,
|
||||
NULL, NULL,
|
||||
resuming);
|
||||
else
|
||||
result = query_recurse(client, qtype,
|
||||
fname, rdataset,
|
||||
resuming);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
client->query.attributes |=
|
||||
NS_QUERYATTR_RECURSING;
|
||||
if (dns64)
|
||||
client->query.attributes |=
|
||||
NS_QUERYATTR_DNS64;
|
||||
if (dns64_exclude)
|
||||
client->query.attributes |=
|
||||
NS_QUERYATTR_DNS64EXCLUDE;
|
||||
} else if (result == DNS_R_DUPLICATE ||
|
||||
result == DNS_R_DROP)
|
||||
QUERY_ERROR(result);
|
||||
else
|
||||
RECURSE_ERROR(result);
|
||||
} else {
|
||||
|
|
@ -4251,11 +4679,74 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
}
|
||||
}
|
||||
goto cleanup;
|
||||
|
||||
case DNS_R_EMPTYNAME:
|
||||
result = DNS_R_NXRRSET;
|
||||
/* FALLTHROUGH */
|
||||
case DNS_R_NXRRSET:
|
||||
nxrrset:
|
||||
INSIST(is_zone);
|
||||
|
||||
#ifdef dns64_bis_return_excluded_addresses
|
||||
if (dns64)
|
||||
#else
|
||||
if (dns64 && !dns64_exclude)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Restore the answers from the previous AAAA lookup.
|
||||
*/
|
||||
if (rdataset != NULL)
|
||||
query_putrdataset(client, &rdataset);
|
||||
if (sigrdataset != NULL)
|
||||
query_putrdataset(client, &sigrdataset);
|
||||
rdataset = client->query.dns64_aaaa;
|
||||
sigrdataset = client->query.dns64_sigaaaa;
|
||||
if (fname == NULL) {
|
||||
dbuf = query_getnamebuf(client);
|
||||
if (dbuf == NULL) {
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
}
|
||||
fname = query_newname(client, dbuf, &b);
|
||||
if (fname == NULL) {
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
dns_name_copy(client->query.qname, fname, NULL);
|
||||
client->query.dns64_aaaa = NULL;
|
||||
client->query.dns64_sigaaaa = NULL;
|
||||
dns64 = ISC_FALSE;
|
||||
#ifdef dns64_bis_return_excluded_addresses
|
||||
/*
|
||||
* Resume the diverted processing of the AAAA response?
|
||||
*/
|
||||
if (dns64_excluded)
|
||||
break;
|
||||
#endif
|
||||
} else if (result == DNS_R_NXRRSET &&
|
||||
!ISC_LIST_EMPTY(client->view->dns64) &&
|
||||
client->message->rdclass == dns_rdataclass_in &&
|
||||
qtype == dns_rdatatype_aaaa)
|
||||
{
|
||||
/*
|
||||
* Look to see if there are A records for this
|
||||
* name.
|
||||
*/
|
||||
INSIST(client->query.dns64_aaaa == NULL);
|
||||
INSIST(client->query.dns64_sigaaaa == NULL);
|
||||
client->query.dns64_aaaa = rdataset;
|
||||
client->query.dns64_sigaaaa = sigrdataset;
|
||||
query_releasename(client, &fname);
|
||||
dns_db_detachnode(db, &node);
|
||||
rdataset = NULL;
|
||||
sigrdataset = NULL;
|
||||
type = qtype = dns_rdatatype_a;
|
||||
dns64 = ISC_TRUE;
|
||||
goto db_find;
|
||||
}
|
||||
|
||||
result = DNS_R_NXRRSET;
|
||||
|
||||
/*
|
||||
* Look for a NSEC3 record if we don't have a NSEC record.
|
||||
*/
|
||||
|
|
@ -4348,7 +4839,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
/*
|
||||
* Add SOA.
|
||||
*/
|
||||
result = query_addsoa(client, db, version, ISC_FALSE,
|
||||
result = query_addsoa(client, db, version, ISC_UINT32_MAX,
|
||||
dns_rdataset_isassociated(rdataset));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
QUERY_ERROR(result);
|
||||
|
|
@ -4397,10 +4888,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
zone != NULL &&
|
||||
#endif
|
||||
dns_zone_getzeronosoattl(zone))
|
||||
result = query_addsoa(client, db, version, ISC_TRUE,
|
||||
result = query_addsoa(client, db, version, 0,
|
||||
dns_rdataset_isassociated(rdataset));
|
||||
else
|
||||
result = query_addsoa(client, db, version, ISC_FALSE,
|
||||
result = query_addsoa(client, db, version,
|
||||
ISC_UINT32_MAX,
|
||||
dns_rdataset_isassociated(rdataset));
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
QUERY_ERROR(result);
|
||||
|
|
@ -4431,6 +4923,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
|
||||
case DNS_R_NCACHENXDOMAIN:
|
||||
case DNS_R_NCACHENXRRSET:
|
||||
ncache_nxrrset:
|
||||
INSIST(!is_zone);
|
||||
authoritative = ISC_FALSE;
|
||||
/*
|
||||
|
|
@ -4446,6 +4939,66 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
client->message->rdclass == dns_rdataclass_in &&
|
||||
dns_name_countlabels(fname) == 7)
|
||||
warn_rfc1918(client, fname, rdataset);
|
||||
|
||||
#ifdef dns64_bis_return_excluded_addresses
|
||||
if (dns64)
|
||||
#else
|
||||
if (dns64 && !dns64_exclude)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Restore the answers from the previous AAAA lookup.
|
||||
*/
|
||||
if (rdataset != NULL)
|
||||
query_putrdataset(client, &rdataset);
|
||||
if (sigrdataset != NULL)
|
||||
query_putrdataset(client, &sigrdataset);
|
||||
rdataset = client->query.dns64_aaaa;
|
||||
sigrdataset = client->query.dns64_sigaaaa;
|
||||
if (fname == NULL) {
|
||||
dbuf = query_getnamebuf(client);
|
||||
if (dbuf == NULL) {
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
}
|
||||
fname = query_newname(client, dbuf, &b);
|
||||
if (fname == NULL) {
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
dns_name_copy(client->query.qname, fname, NULL);
|
||||
client->query.dns64_aaaa = NULL;
|
||||
client->query.dns64_sigaaaa = NULL;
|
||||
dns64 = ISC_FALSE;
|
||||
#ifdef dns64_bis_return_excluded_addresses
|
||||
if (dns64_excluded)
|
||||
break;
|
||||
#endif
|
||||
} else if (result == DNS_R_NCACHENXRRSET &&
|
||||
!ISC_LIST_EMPTY(client->view->dns64) &&
|
||||
client->message->rdclass == dns_rdataclass_in &&
|
||||
qtype == dns_rdatatype_aaaa)
|
||||
{
|
||||
/*
|
||||
* Look to see if there are A records for this
|
||||
* name.
|
||||
*/
|
||||
INSIST(client->query.dns64_aaaa == NULL);
|
||||
INSIST(client->query.dns64_sigaaaa == NULL);
|
||||
client->query.dns64_aaaa = rdataset;
|
||||
client->query.dns64_sigaaaa = sigrdataset;
|
||||
client->query.dns64_ttl = rdataset->ttl;
|
||||
query_releasename(client, &fname);
|
||||
dns_db_detachnode(db, &node);
|
||||
rdataset = NULL;
|
||||
sigrdataset = NULL;
|
||||
fname = NULL;
|
||||
type = qtype = dns_rdatatype_a;
|
||||
dns64 = ISC_TRUE;
|
||||
goto db_find;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't call query_addrrset() because we don't need any
|
||||
* of its extra features (and things would probably break!).
|
||||
|
|
@ -4831,7 +5384,8 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
* Add SOA.
|
||||
*/
|
||||
result = query_addsoa(client, db, version,
|
||||
ISC_FALSE, ISC_FALSE);
|
||||
ISC_UINT32_MAX,
|
||||
ISC_FALSE);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = ISC_R_NOMORE;
|
||||
} else {
|
||||
|
|
@ -4937,6 +5491,32 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Check to see if the AAAA RRset has non-excluded addresses
|
||||
* in it. If not look for a A RRset.
|
||||
*/
|
||||
INSIST(client->query.dns64_aaaaok == NULL);
|
||||
|
||||
if (qtype == dns_rdatatype_aaaa && !dns64_exclude &&
|
||||
!ISC_LIST_EMPTY(client->view->dns64) &&
|
||||
client->message->rdclass == dns_rdataclass_in &&
|
||||
!dns64_aaaaok(client, rdataset, sigrdataset)) {
|
||||
/*
|
||||
* Look to see if there are A records for this
|
||||
* name.
|
||||
*/
|
||||
client->query.dns64_aaaa = rdataset;
|
||||
client->query.dns64_sigaaaa = sigrdataset;
|
||||
client->query.dns64_ttl = rdataset->ttl;
|
||||
query_releasename(client, &fname);
|
||||
dns_db_detachnode(db, &node);
|
||||
rdataset = NULL;
|
||||
sigrdataset = NULL;
|
||||
type = qtype = dns_rdatatype_a;
|
||||
dns64_exclude = dns64 = ISC_TRUE;
|
||||
goto db_find;
|
||||
}
|
||||
|
||||
if (sigrdataset != NULL)
|
||||
sigrdatasetp = &sigrdataset;
|
||||
else
|
||||
|
|
@ -4952,8 +5532,43 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
dns_name_equal(client->query.qname, dns_rootname))
|
||||
client->query.attributes &= ~NS_QUERYATTR_NOADDITIONAL;
|
||||
|
||||
query_addrrset(client, &fname, &rdataset, sigrdatasetp, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
if (dns64) {
|
||||
qtype = type = dns_rdatatype_aaaa;
|
||||
result = query_dns64(client, &fname, rdataset,
|
||||
sigrdataset, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
dns_message_puttemprdataset(client->message, &rdataset);
|
||||
if (result == ISC_R_NOMORE) {
|
||||
#ifndef dns64_bis_return_excluded_addresses
|
||||
if (dns64_exclude) {
|
||||
if (!is_zone)
|
||||
goto cleanup;
|
||||
/*
|
||||
* Add a fake the SOA record.
|
||||
*/
|
||||
result = query_addsoa(client, db,
|
||||
version, 600,
|
||||
ISC_FALSE);
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
if (is_zone)
|
||||
goto nxrrset;
|
||||
else
|
||||
goto ncache_nxrrset;
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
eresult = result;
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (client->query.dns64_aaaaok != NULL) {
|
||||
query_filter64(client, &fname, rdataset, dbuf,
|
||||
DNS_SECTION_ANSWER);
|
||||
query_putrdataset(client, &rdataset);
|
||||
} else
|
||||
query_addrrset(client, &fname, &rdataset,
|
||||
sigrdatasetp, dbuf, DNS_SECTION_ANSWER);
|
||||
|
||||
if (noqname != NULL)
|
||||
query_addnoqnameproof(client, noqname);
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: server.c,v 1.587 2010/12/02 23:22:41 marka Exp $ */
|
||||
/* $Id: server.c,v 1.588 2010/12/08 02:46:15 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -63,6 +63,7 @@
|
|||
#ifdef DLZ
|
||||
#include <dns/dlz.h>
|
||||
#endif
|
||||
#include <dns/dns64.h>
|
||||
#include <dns/forward.h>
|
||||
#include <dns/journal.h>
|
||||
#include <dns/keytable.h>
|
||||
|
|
@ -1356,6 +1357,7 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
|
|||
isc_boolean_t zero_no_soattl;
|
||||
cfg_parser_t *newzones_parser = NULL;
|
||||
cfg_obj_t *nzfconf = NULL;
|
||||
dns_acl_t *clients = NULL, *mapped = NULL, *excluded = NULL;
|
||||
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
||||
|
|
@ -1618,6 +1620,89 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
|
|||
INSIST(result == ISC_R_SUCCESS);
|
||||
zero_no_soattl = cfg_obj_asboolean(obj);
|
||||
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "dns64", &obj);
|
||||
if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") &&
|
||||
strcmp(view->name, "_meta")) {
|
||||
const cfg_listelt_t *element;
|
||||
isc_netaddr_t na, suffix, *sp;
|
||||
unsigned int prefixlen;
|
||||
|
||||
for (element = cfg_list_first(obj);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
const cfg_obj_t *map = cfg_listelt_value(element);
|
||||
dns_dns64_t *dns64 = NULL;
|
||||
unsigned int dns64options = 0;
|
||||
|
||||
cfg_obj_asnetprefix(cfg_map_getname(map), &na,
|
||||
&prefixlen);
|
||||
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(map, "suffix", &obj);
|
||||
if (obj != NULL) {
|
||||
sp = &suffix;
|
||||
isc_netaddr_fromsockaddr(sp,
|
||||
cfg_obj_assockaddr(obj));
|
||||
} else
|
||||
sp = NULL;
|
||||
|
||||
clients = mapped = excluded = NULL;
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(map, "clients", &obj);
|
||||
if (obj != NULL) {
|
||||
result = cfg_acl_fromconfig(obj, config,
|
||||
ns_g_lctx, actx,
|
||||
mctx, 0, &clients);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
}
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(map, "mapped", &obj);
|
||||
if (obj != NULL) {
|
||||
result = cfg_acl_fromconfig(obj, config,
|
||||
ns_g_lctx, actx,
|
||||
mctx, 0, &mapped);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
}
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(map, "exclude", &obj);
|
||||
if (obj != NULL) {
|
||||
result = cfg_acl_fromconfig(obj, config,
|
||||
ns_g_lctx, actx,
|
||||
mctx, 0, &excluded);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(map, "recursive-only", &obj);
|
||||
if (obj != NULL && cfg_obj_asboolean(obj))
|
||||
dns64options |= DNS_DNS64_RECURSIVE_ONLY;
|
||||
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(map, "break-dnssec", &obj);
|
||||
if (obj != NULL && cfg_obj_asboolean(obj))
|
||||
dns64options |= DNS_DNS64_BREAK_DNSSEC;
|
||||
|
||||
result = dns_dns64_create(mctx, &na, prefixlen, sp,
|
||||
clients, mapped, excluded,
|
||||
dns64options, &dns64);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup;
|
||||
dns_dns64_append(&view->dns64, dns64);
|
||||
view->dns64cnt++;
|
||||
if (clients != NULL)
|
||||
dns_acl_detach(&clients);
|
||||
if (mapped != NULL)
|
||||
dns_acl_detach(&mapped);
|
||||
if (excluded != NULL)
|
||||
dns_acl_detach(&excluded);
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = ns_config_get(maps, "dnssec-accept-expired", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
|
|
@ -2518,6 +2603,12 @@ configure_view(dns_view_t *view, cfg_parser_t* parser,
|
|||
result = ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (clients != NULL)
|
||||
dns_acl_detach(&clients);
|
||||
if (mapped != NULL)
|
||||
dns_acl_detach(&mapped);
|
||||
if (excluded != NULL)
|
||||
dns_acl_detach(&excluded);
|
||||
if (ring != NULL)
|
||||
dns_tsigkeyring_destroy(&ring);
|
||||
if (zone != NULL)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: conf.sh.in,v 1.53 2010/12/07 02:53:33 marka Exp $
|
||||
# $Id: conf.sh.in,v 1.54 2010/12/08 02:46:15 marka Exp $
|
||||
|
||||
#
|
||||
# Common configuration data for system tests, to be sourced into
|
||||
|
|
@ -53,7 +53,7 @@ JOURNALPRINT=$TOP/bin/tools/named-journalprint
|
|||
# load on the machine to make it unusable to other users.
|
||||
# v6synth
|
||||
SUBDIRS="acl allow_query addzone autosign cacheclean checkconf checknames
|
||||
dlv @DLZ_SYSTEM_TEST@ dnssec forward glue ixfr limits lwresd
|
||||
dlv @DLZ_SYSTEM_TEST@ dns64 dnssec forward glue ixfr limits lwresd
|
||||
masterfile masterformat metadata notify nsupdate pending pkcs11
|
||||
resolver rrsetorder sortlist smartsign stub tkey unknown upforwd
|
||||
views xfer xferquota zonechecks"
|
||||
|
|
|
|||
6
bin/tests/system/dns64/clean.sh
Normal file
6
bin/tests/system/dns64/clean.sh
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
|
||||
rm -f ns1/K*
|
||||
rm -f ns1/signed.db*
|
||||
rm -f ns1/dsset-signed.
|
||||
36
bin/tests/system/dns64/ns1/example.db
Normal file
36
bin/tests/system/dns64/ns1/example.db
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
; Copyright
|
||||
$TTL 3600
|
||||
@ SOA ns1 marka.isc.org. 0 0 0 0 1200
|
||||
@ NS ns1
|
||||
ns1 A 10.53.0.1
|
||||
excluded-good-a AAAA 2001:eeee::1
|
||||
A 1.2.3.4
|
||||
excluded-bad-a AAAA 2001:eeee::2
|
||||
A 10.0.0.1
|
||||
excluded-only AAAA 2001:eeee::3
|
||||
partially-excluded-good-a AAAA 2001:eeee::1
|
||||
AAAA 2001::1
|
||||
A 1.2.3.4
|
||||
partially-excluded-bad-a AAAA 2001:eeee::2
|
||||
AAAA 2001::2
|
||||
A 10.0.0.1
|
||||
partially-excluded-only AAAA 2001:eeee::3
|
||||
AAAA 2001::3
|
||||
a-only A 1.2.3.5
|
||||
a-and-aaaa AAAA 2001::1
|
||||
A 1.2.3.6
|
||||
aaaa-only AAAA 2001::2
|
||||
a-not-mapped A 10.0.0.2
|
||||
mx-only MX 10 ns.example.
|
||||
cname-excluded-good-a CNAME excluded-good-a
|
||||
cname-excluded-bad-a CNAME excluded-bad-a
|
||||
cname-excluded-only CNAME excluded-only
|
||||
cname-partial-excluded-good-a CNAME partial-excluded-good-a
|
||||
cname-partial-excluded-bad-a CNAME partial-excluded-bad-a
|
||||
cname-partial-excluded-only CNAME partial-excluded-only
|
||||
cname-a-only CNAME a-only
|
||||
cname-a-and-aaaa CNAME a-and-aaaa
|
||||
cname-aaaa-only CNAME aaaa-only
|
||||
cname-a-not-mapped CNAME a-not-mapped
|
||||
cname-mx-only CNAME mx-only
|
||||
cname-non-existent CNAME non-existent
|
||||
63
bin/tests/system/dns64/ns1/named.conf
Normal file
63
bin/tests/system/dns64/ns1/named.conf
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (C) 2000, 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.
|
||||
*/
|
||||
|
||||
/* $Id: named.conf,v 1.2 2010/12/08 02:46:15 marka Exp $ */
|
||||
|
||||
// NS1
|
||||
|
||||
controls { /* empty */ };
|
||||
|
||||
acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.1;
|
||||
notify-source 10.53.0.1;
|
||||
transfer-source 10.53.0.1;
|
||||
port 5300;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.1; };
|
||||
listen-on-v6 { none; };
|
||||
allow-recursion { 10.53.0.1; };
|
||||
notify yes;
|
||||
dnssec-enable yes;
|
||||
dnssec-validation yes;
|
||||
|
||||
dns64 2001:bbbb::/96 {
|
||||
clients { any; };
|
||||
mapped { !rfc1918; any; };
|
||||
exclude { 2001:eeee::/32; 64:FF9B::/96; ::ffff:0000:0000/96; };
|
||||
suffix ::;
|
||||
recursive-only yes;
|
||||
};
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type master;
|
||||
file "root.db";
|
||||
};
|
||||
|
||||
zone "example" {
|
||||
type master;
|
||||
file "example.db";
|
||||
};
|
||||
|
||||
zone "signed" {
|
||||
type master;
|
||||
file "signed.db.signed";
|
||||
};
|
||||
|
||||
// include "trusted.conf";
|
||||
9
bin/tests/system/dns64/ns1/root.db
Normal file
9
bin/tests/system/dns64/ns1/root.db
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
; Copyright
|
||||
$TTL 3600
|
||||
@ SOA a.root-servers.nil. marka.isc.org. 0 0 0 0 0
|
||||
@ NS a.root-servers.nil.
|
||||
a.root-servers.nil. A 10.53.0.1
|
||||
example NS ns1.example.
|
||||
ns1.example. A 10.53.0.1
|
||||
signed NS ns1.example.
|
||||
ns1.signed. A 10.53.0.1
|
||||
34
bin/tests/system/dns64/ns1/sign.sh
Normal file
34
bin/tests/system/dns64/ns1/sign.sh
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# Copyright (C) 2004, 2006-2010 Internet Systems Consortium, Inc. ("ISC")
|
||||
# Copyright (C) 2000-2003 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.
|
||||
|
||||
# $Id: sign.sh,v 1.2 2010/12/08 02:46:16 marka Exp $
|
||||
|
||||
SYSTEMTESTTOP=../..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
RANDFILE=../random.data
|
||||
|
||||
zone=signed
|
||||
infile=example.db
|
||||
zonefile=signed.db
|
||||
|
||||
key1=`$KEYGEN -q -r $RANDFILE $zone`
|
||||
key2=`$KEYGEN -q -r $RANDFILE -fk $zone`
|
||||
|
||||
cat $infile $key1.key $key2.key > $zonefile
|
||||
|
||||
$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null
|
||||
57
bin/tests/system/dns64/ns2/named.conf
Normal file
57
bin/tests/system/dns64/ns2/named.conf
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
/* $Id: named.conf,v 1.2 2010/12/08 02:46:16 marka Exp $ */
|
||||
|
||||
// NS2
|
||||
|
||||
controls { /* empty */ };
|
||||
|
||||
acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.2;
|
||||
notify-source 10.53.0.2;
|
||||
transfer-source 10.53.0.2;
|
||||
port 5300;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.2; };
|
||||
listen-on-v6 { none; };
|
||||
recursion yes;
|
||||
notify yes;
|
||||
dnssec-enable yes;
|
||||
dnssec-validation yes;
|
||||
|
||||
dns64 2001:aaaa::/96 {
|
||||
clients { 10.53.0.2; };
|
||||
mapped { !rfc1918; any; };
|
||||
exclude { 2001:eeee::/32; 64:FF9B::/96; ::ffff:0000:0000/96; };
|
||||
suffix ::;
|
||||
};
|
||||
|
||||
dns64 64:FF9B::/96 {
|
||||
clients { 10.53.0.1; };
|
||||
mapped { !192.228.79.201; !rfc1918; any; };
|
||||
exclude { 64:FF9B::/96; ::ffff:0000:0000/96; };
|
||||
suffix ::;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type hint;
|
||||
file "../../common/root.hint";
|
||||
};
|
||||
24
bin/tests/system/dns64/setup.sh
Normal file
24
bin/tests/system/dns64/setup.sh
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
|
||||
# Copyright (C) 2000, 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.
|
||||
|
||||
# $Id: setup.sh,v 1.2 2010/12/08 02:46:15 marka Exp $
|
||||
|
||||
../../../tools/genrandom 400 random.data
|
||||
|
||||
sh clean.sh
|
||||
|
||||
cd ns1 && sh sign.sh
|
||||
1248
bin/tests/system/dns64/tests.sh
Normal file
1248
bin/tests/system/dns64/tests.sh
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -18,7 +18,7 @@
|
|||
- PERFORMANCE OF THIS SOFTWARE.
|
||||
-->
|
||||
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.465 2010/09/21 19:47:57 ebersman Exp $ -->
|
||||
<!-- File: $Id: Bv9ARM-book.xml,v 1.466 2010/12/08 02:46:16 marka Exp $ -->
|
||||
<book xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<title>BIND 9 Administrator Reference Manual</title>
|
||||
|
||||
|
|
@ -5120,6 +5120,14 @@ badresp:1,adberr:0,findfail:0,valfail:0]
|
|||
<optional> match-mapped-addresses <replaceable>yes_or_no</replaceable>; </optional>
|
||||
<optional> filter-aaaa-on-v4 ( <replaceable>yes_or_no</replaceable> | <replaceable>break-dnssec</replaceable> ); </optional>
|
||||
<optional> filter-aaaa { <replaceable>address_match_list</replaceable> }; </optional>
|
||||
<optional> dns64 <replaceable>IPv6-prefix</replaceable> {
|
||||
<optional> clients { <replaceable>address_match_list</replaceable> }; </optional>
|
||||
<optional> mapped { <replaceable>address_match_list</replaceable> }; </optional>
|
||||
<optional> exclude { <replaceable>address_match_list</replaceable> }; </optional>
|
||||
<optional> suffix IPv6-address; </optional>
|
||||
<optional> recursion-only <replaceable>yes_or_no</replaceable>; </optional>
|
||||
<optional> break-dnssec <replaceable>yes_or_no</replaceable>; </optional>
|
||||
}; </optional>;
|
||||
<optional> preferred-glue ( <replaceable>A</replaceable> | <replaceable>AAAA</replaceable> | <replaceable>NONE</replaceable> ); </optional>
|
||||
<optional> edns-udp-size <replaceable>number</replaceable>; </optional>
|
||||
<optional> max-udp-size <replaceable>number</replaceable>; </optional>
|
||||
|
|
@ -5710,6 +5718,63 @@ options {
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>dns64</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This directive instructs <command>named</command> to
|
||||
return mapped IPv4 addresses to AAAA queries when
|
||||
there are no AAAA records. It is intended to be
|
||||
used in conjunction with a NAT64. Each
|
||||
<command>dns64</command> defines one DNS64 prefix.
|
||||
Multiple DNS64 prefixes can be defined.
|
||||
</para>
|
||||
<para>
|
||||
Compatible IPv6 prefixes have lengths of 32, 40, 48, 56,
|
||||
64 and 96 as per RFC 6052.
|
||||
</para>
|
||||
<para>
|
||||
Each <command>dns64</command> supports a optional
|
||||
<command>clients</command> acl which defines which clients
|
||||
see this directive. If not defined it defaults to
|
||||
<userinput>any;</userinput>.
|
||||
</para>
|
||||
<para>
|
||||
Each <command>dns64</command> supports a optional
|
||||
<command>mapped</command> acl which selects which
|
||||
IPv4 addresses are to be mapped are in the corresponding
|
||||
A RRset. If not defined it defaults to
|
||||
<userinput>any;</userinput>.
|
||||
</para>
|
||||
<para>
|
||||
Each <command>dns64</command> supports a optional
|
||||
<command>exclude</command> acl which selects which
|
||||
IPv6 addresses will be ignored for the purposes
|
||||
of determining if dns64 is to be applied. Any
|
||||
non matching address will prevent any further
|
||||
DNS64 processing from occuring for this client.
|
||||
</para>
|
||||
<para>
|
||||
A optional <command>suffix</command> can also
|
||||
be defined to set the bits trailing the mapped
|
||||
IPv4 address bits. By default these bits are
|
||||
set to <userinput>::</userinput>. The bits
|
||||
matching the prefix and mapped IPv4 address
|
||||
must be zero.
|
||||
</para>
|
||||
<programlisting>
|
||||
acl rfc1918 { 10/8; 192.168/16; 172.16/12; };
|
||||
|
||||
dns64 64:FF9B::/96 {
|
||||
clients { any; };
|
||||
mapped { !rfc1918; any; };
|
||||
exclude { 64:FF9B::/96; ::ffff:0000:0000/96; };
|
||||
suffix ::;
|
||||
};
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<sect3 id="boolean_options">
|
||||
|
|
|
|||
|
|
@ -100,6 +100,14 @@ options {
|
|||
directory <quoted_string>;
|
||||
disable-algorithms <string> { <string>; ... };
|
||||
disable-empty-zone <string>;
|
||||
dns64 <netprefix> {
|
||||
break-dnssec <boolean>;
|
||||
clients { <address_match_element>; ... };
|
||||
exclude { <address_match_element>; ... };
|
||||
mapped { <address_match_element>; ... };
|
||||
recursive-only <boolean>;
|
||||
suffix <ipv6_address>;
|
||||
};
|
||||
dnssec-accept-expired <boolean>;
|
||||
dnssec-dnskey-kskonly <boolean>;
|
||||
dnssec-enable <boolean>;
|
||||
|
|
@ -303,6 +311,14 @@ view <string> <optional_class> {
|
|||
dlz <string> {
|
||||
database <string>;
|
||||
};
|
||||
dns64 <netprefix> {
|
||||
break-dnssec <boolean>;
|
||||
clients { <address_match_element>; ... };
|
||||
exclude { <address_match_element>; ... };
|
||||
mapped { <address_match_element>; ... };
|
||||
recursive-only <boolean>;
|
||||
suffix <ipv6_address>;
|
||||
};
|
||||
dnssec-accept-expired <boolean>;
|
||||
dnssec-dnskey-kskonly <boolean>;
|
||||
dnssec-enable <boolean>;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: check.c,v 1.120 2010/08/11 18:14:19 each Exp $ */
|
||||
/* $Id: check.c,v 1.121 2010/12/08 02:46:16 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -418,6 +418,106 @@ check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
|
|||
return (result);
|
||||
}
|
||||
|
||||
static const unsigned char zeros[16];
|
||||
|
||||
static isc_result_t
|
||||
check_dns64(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions,
|
||||
const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx)
|
||||
{
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
const cfg_obj_t *dns64 = NULL;
|
||||
const cfg_obj_t *options;
|
||||
const cfg_listelt_t *element;
|
||||
const cfg_obj_t *map, *obj;
|
||||
isc_netaddr_t na, sa;
|
||||
unsigned int prefixlen;
|
||||
int nbytes;
|
||||
int i;
|
||||
|
||||
static const char *acls[] = { "client", "exclude", "mapped", NULL};
|
||||
|
||||
if (voptions != NULL)
|
||||
cfg_map_get(voptions, "dns64", &dns64);
|
||||
if (config != NULL && dns64 == NULL) {
|
||||
options = NULL;
|
||||
cfg_map_get(config, "options", &options);
|
||||
if (options != NULL)
|
||||
cfg_map_get(options, "dns64", &dns64);
|
||||
}
|
||||
if (dns64 == NULL)
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
for (element = cfg_list_first(dns64);
|
||||
element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
map = cfg_listelt_value(element);
|
||||
obj = cfg_map_getname(map);
|
||||
|
||||
cfg_obj_asnetprefix(obj, &na, &prefixlen);
|
||||
if (na.family != AF_INET6) {
|
||||
cfg_obj_log(map, logctx, ISC_LOG_ERROR,
|
||||
"dns64 requires a IPv6 prefix");
|
||||
result = ISC_R_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prefixlen != 32 && prefixlen != 40 && prefixlen != 48 &&
|
||||
prefixlen != 56 && prefixlen != 64 && prefixlen != 96) {
|
||||
cfg_obj_log(map, logctx, ISC_LOG_ERROR,
|
||||
"bad prefix length %u [32/40/48/56/64/96]",
|
||||
prefixlen);
|
||||
result = ISC_R_FAILURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; acls[i] != NULL; i++) {
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(map, acls[i], &obj);
|
||||
if (obj != NULL) {
|
||||
dns_acl_t *acl = NULL;
|
||||
isc_result_t tresult;
|
||||
|
||||
tresult = cfg_acl_fromconfig(obj, config,
|
||||
logctx, actx,
|
||||
mctx, 0, &acl);
|
||||
if (acl != NULL)
|
||||
dns_acl_detach(&acl);
|
||||
if (tresult != ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(map, "suffix", &obj);
|
||||
if (obj != NULL) {
|
||||
isc_netaddr_fromsockaddr(&sa, cfg_obj_assockaddr(obj));
|
||||
if (sa.family != AF_INET6) {
|
||||
cfg_obj_log(map, logctx, ISC_LOG_ERROR,
|
||||
"dns64 requires a IPv6 suffix");
|
||||
result = ISC_R_FAILURE;
|
||||
continue;
|
||||
}
|
||||
nbytes = prefixlen / 8 + 4;
|
||||
if (prefixlen >= 32 && prefixlen <= 64)
|
||||
nbytes++;
|
||||
if (memcmp(sa.type.in6.s6_addr, zeros, nbytes) != 0) {
|
||||
char netaddrbuf[ISC_NETADDR_FORMATSIZE];
|
||||
isc_netaddr_format(&sa, netaddrbuf,
|
||||
sizeof(netaddrbuf));
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"bad suffix '%s' leading "
|
||||
"%u octets not zeros",
|
||||
netaddrbuf, nbytes);
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check allow-recursion and allow-recursion-on acls, and also log a
|
||||
* warning if they're inconsistent with the "recursion" option.
|
||||
|
|
@ -2101,6 +2201,10 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
|||
if (tresult != ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
|
||||
tresult = check_dns64(&actx, voptions, config, logctx, mctx);
|
||||
if (tresult != ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
|
||||
cfg_aclconfctx_clear(&actx);
|
||||
|
||||
return (result);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# $Id: Makefile.in,v 1.171 2010/06/09 23:50:58 tbox Exp $
|
||||
# $Id: Makefile.in,v 1.172 2010/12/08 02:46:16 marka Exp $
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
|
@ -57,8 +57,9 @@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \
|
|||
DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
|
||||
cache.@O@ callbacks.@O@ compress.@O@ \
|
||||
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
|
||||
dlz.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ journal.@O@ \
|
||||
keydata.@O@ keytable.@O@ lib.@O@ log.@O@ lookup.@O@ \
|
||||
dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ \
|
||||
journal.@O@ keydata.@O@ keytable.@O@ \
|
||||
lib.@O@ log.@O@ lookup.@O@ \
|
||||
master.@O@ masterdump.@O@ message.@O@ \
|
||||
name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ order.@O@ peer.@O@ \
|
||||
portlist.@O@ private.@O@ \
|
||||
|
|
@ -85,7 +86,7 @@ DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \
|
|||
DNSSRCS = acache.c acl.c adb.c byaddr.c \
|
||||
cache.c callbacks.c compress.c \
|
||||
db.c dbiterator.c dbtable.c diff.c dispatch.c \
|
||||
dlz.c dnssec.c ds.c forward.c iptable.c journal.c \
|
||||
dlz.c dns64.c dnssec.c ds.c forward.c iptable.c journal.c \
|
||||
keydata.c keytable.c lib.c log.c lookup.c \
|
||||
master.c masterdump.c message.c \
|
||||
name.c ncache.c nsec.c nsec3.c order.c peer.c portlist.c \
|
||||
|
|
|
|||
282
lib/dns/dns64.c
Normal file
282
lib/dns/dns64.c
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* Copyright
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/list.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/acl.h>
|
||||
#include <dns/dns64.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/result.h>
|
||||
|
||||
struct dns_dns64 {
|
||||
unsigned char bits[16]; /*
|
||||
* Prefix + suffix bits.
|
||||
*/
|
||||
dns_acl_t * clients; /*
|
||||
* Which clients get mapped
|
||||
* addresses.
|
||||
*/
|
||||
dns_acl_t * mapped; /*
|
||||
* IPv4 addresses to be mapped.
|
||||
*/
|
||||
dns_acl_t * excluded; /*
|
||||
* IPv6 addresses that are
|
||||
* treated as not existing.
|
||||
*/
|
||||
unsigned int prefixlen; /*
|
||||
* Start of mapped address.
|
||||
*/
|
||||
unsigned int flags;
|
||||
isc_mem_t * mctx;
|
||||
ISC_LINK(dns_dns64_t) link;
|
||||
};
|
||||
|
||||
isc_result_t
|
||||
dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix,
|
||||
unsigned int prefixlen, isc_netaddr_t *suffix,
|
||||
dns_acl_t *clients, dns_acl_t *mapped, dns_acl_t *excluded,
|
||||
unsigned int flags, dns_dns64_t **dns64)
|
||||
{
|
||||
dns_dns64_t *new;
|
||||
unsigned int nbytes = 16;
|
||||
|
||||
REQUIRE(prefix != NULL && prefix->family == AF_INET6);
|
||||
/* Legal prefix lengths from draft-ietf-behave-address-format-04. */
|
||||
REQUIRE(prefixlen == 32 || prefixlen == 40 || prefixlen == 48 ||
|
||||
prefixlen == 56 || prefixlen == 64 || prefixlen == 96);
|
||||
REQUIRE(isc_netaddr_prefixok(prefix, prefixlen) == ISC_R_SUCCESS);
|
||||
REQUIRE(dns64 != NULL && *dns64 == NULL);
|
||||
|
||||
if (suffix != NULL) {
|
||||
static const unsigned char zeros[16];
|
||||
REQUIRE(prefix->family == AF_INET6);
|
||||
nbytes = prefixlen / 8 + 4;
|
||||
/* Bits 64-71 are zeros. draft-ietf-behave-address-format-04 */
|
||||
if (prefixlen >= 32 && prefixlen <= 64)
|
||||
nbytes++;
|
||||
REQUIRE(memcmp(suffix->type.in6.s6_addr, zeros, nbytes) == 0);
|
||||
}
|
||||
|
||||
new = isc_mem_get(mctx, sizeof(dns_dns64_t));
|
||||
if (new == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
memset(new->bits, 0, sizeof(new->bits));
|
||||
memcpy(new->bits, prefix->type.in6.s6_addr, prefixlen / 8);
|
||||
if (suffix != NULL)
|
||||
memcpy(new->bits + nbytes, suffix->type.in6.s6_addr + nbytes,
|
||||
16 - nbytes);
|
||||
new->clients = NULL;
|
||||
if (clients != NULL)
|
||||
dns_acl_attach(clients, &new->clients);
|
||||
new->mapped = NULL;
|
||||
if (mapped != NULL)
|
||||
dns_acl_attach(mapped, &new->mapped);
|
||||
new->excluded = NULL;
|
||||
if (excluded != NULL)
|
||||
dns_acl_attach(excluded, &new->excluded);
|
||||
new->prefixlen = prefixlen;
|
||||
new->flags = flags;
|
||||
ISC_LINK_INIT(new, link);
|
||||
new->mctx = NULL;
|
||||
isc_mem_attach(mctx, &new->mctx);
|
||||
*dns64 = new;
|
||||
return (ISC_R_SUCCESS);
|
||||
};
|
||||
|
||||
void
|
||||
dns_dns64_destroy(dns_dns64_t **dns64p) {
|
||||
dns_dns64_t *dns64;
|
||||
|
||||
REQUIRE(dns64p != NULL && *dns64p != NULL);
|
||||
|
||||
dns64 = *dns64p;
|
||||
*dns64p = NULL;
|
||||
|
||||
REQUIRE(!ISC_LINK_LINKED(dns64, link));
|
||||
|
||||
if (dns64->clients != NULL)
|
||||
dns_acl_detach(&dns64->clients);
|
||||
if (dns64->mapped != NULL)
|
||||
dns_acl_detach(&dns64->mapped);
|
||||
if (dns64->excluded != NULL)
|
||||
dns_acl_detach(&dns64->excluded);
|
||||
isc_mem_putanddetach(&dns64->mctx, dns64, sizeof(*dns64));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
|
||||
const dns_name_t *reqsigner, const dns_aclenv_t *env,
|
||||
unsigned int flags, unsigned char *a, unsigned char *aaaa)
|
||||
{
|
||||
unsigned int nbytes, i;
|
||||
isc_result_t result;
|
||||
int match;
|
||||
|
||||
if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 &&
|
||||
(flags & DNS_DNS64_RECURSIVE) == 0)
|
||||
return (DNS_R_DISALLOWED);
|
||||
|
||||
if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 &&
|
||||
(flags & DNS_DNS64_DNSSEC) != 0)
|
||||
return (DNS_R_DISALLOWED);
|
||||
|
||||
if (dns64->clients != NULL) {
|
||||
result = dns_acl_match(reqaddr, reqsigner, dns64->clients, env,
|
||||
&match, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
if (match <= 0)
|
||||
return (DNS_R_DISALLOWED);
|
||||
}
|
||||
|
||||
if (dns64->mapped != NULL) {
|
||||
struct in_addr ina;
|
||||
isc_netaddr_t netaddr;
|
||||
|
||||
memcpy(&ina.s_addr, a, 4);
|
||||
isc_netaddr_fromin(&netaddr, &ina);
|
||||
result = dns_acl_match(&netaddr, NULL, dns64->mapped, env,
|
||||
&match, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
if (match <= 0)
|
||||
return (DNS_R_DISALLOWED);
|
||||
}
|
||||
|
||||
nbytes = dns64->prefixlen / 8;
|
||||
INSIST(nbytes <= 12);
|
||||
/* Copy prefix. */
|
||||
memcpy(aaaa, dns64->bits, nbytes);
|
||||
/* Copy mapped address. */
|
||||
for (i = 0; i < 4U; i++) {
|
||||
aaaa[nbytes++] = a[i];
|
||||
/* Bits 64-71 are zeros. draft-ietf-behave-address-format-04 */
|
||||
if (nbytes == 8)
|
||||
aaaa[nbytes++] = 0;
|
||||
}
|
||||
/* Copy suffix. */
|
||||
memcpy(aaaa + nbytes, dns64->bits + nbytes, 16 - nbytes);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_dns64_t *
|
||||
dns_dns64_next(dns_dns64_t *dns64) {
|
||||
dns64 = ISC_LIST_NEXT(dns64, link);
|
||||
return (dns64);
|
||||
}
|
||||
|
||||
void
|
||||
dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64) {
|
||||
ISC_LIST_APPEND(*list, dns64, link);
|
||||
}
|
||||
|
||||
void
|
||||
dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64) {
|
||||
ISC_LIST_UNLINK(*list, dns64, link);
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
|
||||
const dns_name_t *reqsigner, const dns_aclenv_t *env,
|
||||
unsigned int flags, dns_rdataset_t *rdataset,
|
||||
isc_boolean_t *aaaaok, size_t aaaaoklen)
|
||||
{
|
||||
struct in6_addr in6;
|
||||
isc_netaddr_t netaddr;
|
||||
isc_result_t result;
|
||||
int match;
|
||||
isc_boolean_t answer = ISC_FALSE;
|
||||
isc_boolean_t found = ISC_FALSE;
|
||||
unsigned int i, ok;
|
||||
|
||||
REQUIRE(rdataset != NULL);
|
||||
REQUIRE(rdataset->type == dns_rdatatype_aaaa);
|
||||
REQUIRE(rdataset->rdclass == dns_rdataclass_in);
|
||||
if (aaaaok != NULL)
|
||||
REQUIRE(aaaaoklen == dns_rdataset_count(rdataset));
|
||||
|
||||
for (;dns64 != NULL; dns64 = ISC_LIST_NEXT(dns64, link)) {
|
||||
if ((dns64->flags & DNS_DNS64_RECURSIVE_ONLY) != 0 &&
|
||||
(flags & DNS_DNS64_RECURSIVE) == 0)
|
||||
continue;
|
||||
|
||||
if ((dns64->flags & DNS_DNS64_BREAK_DNSSEC) == 0 &&
|
||||
(flags & DNS_DNS64_DNSSEC) != 0)
|
||||
continue;
|
||||
/*
|
||||
* Work out if this dns64 structure applies to this client.
|
||||
*/
|
||||
if (dns64->clients != NULL) {
|
||||
result = dns_acl_match(reqaddr, reqsigner,
|
||||
dns64->clients, env,
|
||||
&match, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
continue;
|
||||
if (match <= 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!found && aaaaok != NULL) {
|
||||
for (i = 0; i < aaaaoklen; i++)
|
||||
aaaaok[i] = ISC_FALSE;
|
||||
}
|
||||
found = ISC_TRUE;
|
||||
|
||||
/*
|
||||
* If we are not excluding any addresses then any AAAA
|
||||
* will do.
|
||||
*/
|
||||
if (dns64->excluded == NULL) {
|
||||
answer = ISC_TRUE;
|
||||
for (i = 0; i < aaaaoklen; i++)
|
||||
aaaaok[i] = ISC_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
i = 0; ok = 0;
|
||||
for (result = dns_rdataset_first(rdataset);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(rdataset)) {
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
if (aaaaok == NULL || !aaaaok[i]) {
|
||||
|
||||
dns_rdataset_current(rdataset, &rdata);
|
||||
memcpy(&in6.s6_addr, rdata.data, 16);
|
||||
isc_netaddr_fromin6(&netaddr, &in6);
|
||||
|
||||
result = dns_acl_match(&netaddr, NULL,
|
||||
dns64->excluded,
|
||||
env, &match, NULL);
|
||||
if (result == ISC_R_SUCCESS && match <= 0) {
|
||||
answer = ISC_TRUE;
|
||||
if (aaaaok == NULL)
|
||||
goto done;
|
||||
aaaaok[i] = ISC_TRUE;
|
||||
ok++;
|
||||
}
|
||||
} else
|
||||
ok++;
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
* Are all addresses ok?
|
||||
*/
|
||||
if (aaaaok != NULL && ok == aaaaoklen)
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (!found && aaaaok != NULL) {
|
||||
for (i = 0; i < aaaaoklen; i++)
|
||||
aaaaok[i] = ISC_TRUE;
|
||||
}
|
||||
return (found ? answer : ISC_TRUE);
|
||||
}
|
||||
161
lib/dns/include/dns/dns64.h
Normal file
161
lib/dns/include/dns/dns64.h
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright
|
||||
*/
|
||||
|
||||
#ifndef DNS_DNS64_H
|
||||
#define DNS_DNS64_H 1
|
||||
|
||||
#include <isc/lang.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
/*
|
||||
* dns_dns64_create() flags.
|
||||
*/
|
||||
#define DNS_DNS64_RECURSIVE_ONLY 0x01 /* If set then this record
|
||||
* only applies to recursive
|
||||
* queries.
|
||||
*/
|
||||
#define DNS_DNS64_BREAK_DNSSEC 0x02 /* If set then still perform
|
||||
* DNSSEC synthesis even
|
||||
* though the result would
|
||||
* fail validation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* dns_dns64_aaaaok() and dns_dns64_aaaafroma() flags.
|
||||
*/
|
||||
#define DNS_DNS64_RECURSIVE 0x01 /* Recursive query. */
|
||||
#define DNS_DNS64_DNSSEC 0x02 /* DNSSEC sensitive query. */
|
||||
|
||||
isc_result_t
|
||||
dns_dns64_create(isc_mem_t *mctx, isc_netaddr_t *prefix,
|
||||
unsigned int prefixlen, isc_netaddr_t *suffix,
|
||||
dns_acl_t *client, dns_acl_t *mapped, dns_acl_t *excluded,
|
||||
unsigned int flags, dns_dns64_t **dns64);
|
||||
/*
|
||||
* Create a dns64 record which is used to identify the set of clients
|
||||
* it applies to and how to perform the DNS64 synthesis.
|
||||
*
|
||||
* 'prefix' and 'prefixlen' defined the leading bits of the AAAA records
|
||||
* to be synthesised. 'suffix' defines the bits after the A records bits.
|
||||
* If suffix is NULL zeros will be used for these bits. 'client' defines
|
||||
* for which clients this record applies. If 'client' is NULL then all
|
||||
* clients apply. 'mapped' defines which A records are candidated for
|
||||
* mapping. If 'mapped' is NULL then all A records will be mapped.
|
||||
* 'excluded' defines which AAAA are to be treated as non-existent for the
|
||||
* purposed of determining whether to perform syntesis. If 'excluded' is
|
||||
* NULL then no AAAA records prevent synthesis.
|
||||
*
|
||||
* If DNS_DNS64_RECURSIVE_ONLY is set then the record will only match if
|
||||
* DNS_DNS64_RECURSIVE is set when calling dns_dns64_aaaaok() and
|
||||
* dns_dns64_aaaafroma().
|
||||
*
|
||||
* If DNS_DNS64_BREAK_DNSSEC is set then the record will still apply if
|
||||
* DNS_DNS64_DNSSEC is set when calling dns_dns64_aaaaok() and
|
||||
* dns_dns64_aaaafroma() otherwise the record will be ignored.
|
||||
*
|
||||
* Requires:
|
||||
* 'mctx' to be valid.
|
||||
* 'prefix' to be valid and the address family to AF_INET6.
|
||||
* 'prefixlen' to be one of 32, 40, 48, 56, 72 and 96.
|
||||
* the bits not covered by prefixlen in prefix to
|
||||
* be zero.
|
||||
* 'suffix' to be NULL or the address family be set to AF_INET6
|
||||
* and the leading 'prefixlen' + 32 bits of the 'suffix'
|
||||
* to be zero. If 'prefixlen' is 40, 48 or 56 then the
|
||||
* the leading 'prefixlen' + 40 bits of 'suffix' must be
|
||||
* zero.
|
||||
* 'client' to be NULL or a valid acl.
|
||||
* 'mapped' to be NULL or a valid acl.
|
||||
* 'exculded' to be NULL or a valid acl.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS
|
||||
* ISC_R_NOMEMORY
|
||||
*/
|
||||
|
||||
void
|
||||
dns_dns64_destroy(dns_dns64_t **dns64p);
|
||||
/*
|
||||
* Destroys a dns64 record.
|
||||
*
|
||||
* Requires the record to not be linked.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
|
||||
const dns_name_t *reqsigner, const dns_aclenv_t *env,
|
||||
unsigned int flags, unsigned char *a, unsigned char *aaaa);
|
||||
/*
|
||||
* dns_dns64_aaaafroma() determines whether to perform a DNS64 address
|
||||
* synthesis from 'a' based on 'dns64', 'reqaddr', 'reqsigner', 'env',
|
||||
* 'flags' and 'aaaa'. If synthesis is performed then the result is
|
||||
* written to '*aaaa'.
|
||||
*
|
||||
* The synthesised address will be of the form:
|
||||
*
|
||||
* <prefix bits><a bits><suffix bits>
|
||||
*
|
||||
* If <a bits> straddle bits 64-71 of the AAAA record, then 8 zero bits will
|
||||
* be inserted at bits 64-71.
|
||||
*
|
||||
* Requires:
|
||||
* 'dns64' to be valid.
|
||||
* 'reqaddr' to be valid.
|
||||
* 'reqsigner' to be NULL or valid.
|
||||
* 'env' to be valid.
|
||||
* 'a' to point to a IPv4 address in network order.
|
||||
* 'aaaa' to point to a IPv6 address buffer in network order.
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS if synthesis was performed.
|
||||
* DNS_R_DISALLOWED if there is no match.
|
||||
*/
|
||||
|
||||
dns_dns64_t *
|
||||
dns_dns64_next(dns_dns64_t *dns64);
|
||||
/*
|
||||
* Return the next dns64 record in the list.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64);
|
||||
/*
|
||||
* Append the dns64 record to the list.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64);
|
||||
/*
|
||||
* Unlink the dns64 record from the list.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
|
||||
const dns_name_t *reqsigner, const dns_aclenv_t *env,
|
||||
unsigned int flags, dns_rdataset_t *rdataset,
|
||||
isc_boolean_t *aaaaok, size_t aaaaoklen);
|
||||
/*
|
||||
* Determine if there are any non-excluded AAAA records in from the
|
||||
* matching dns64 records in the list starting at 'dns64'. If there
|
||||
* is a non-exluded address return ISC_TRUE. If all addresses are
|
||||
* excluded in the matched records return ISC_FALSE. If no records
|
||||
* match then return ISC_TRUE.
|
||||
*
|
||||
* If aaaaok is defined then dns_dns64_aaaaok() return a array of which
|
||||
* addresses in 'rdataset' were deemed to not be exclude by any matching
|
||||
* record. If there are no matching records then all entries are set
|
||||
* to ISC_TRUE.
|
||||
*
|
||||
* Requires
|
||||
* 'rdataset' to be valid and to be for type AAAA and class IN.
|
||||
* 'aaaaoklen' must match the number of records in 'rdataset'
|
||||
* if 'aaaaok' in non NULL.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_DNS64_H */
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: types.h,v 1.142 2010/06/22 03:58:38 marka Exp $ */
|
||||
/* $Id: types.h,v 1.143 2010/12/08 02:46:16 marka Exp $ */
|
||||
|
||||
#ifndef DNS_TYPES_H
|
||||
#define DNS_TYPES_H 1
|
||||
|
|
@ -67,6 +67,8 @@ typedef struct dns_dispatchevent dns_dispatchevent_t;
|
|||
typedef struct dns_dispatchlist dns_dispatchlist_t;
|
||||
typedef struct dns_dispatchmgr dns_dispatchmgr_t;
|
||||
typedef struct dns_dispentry dns_dispentry_t;
|
||||
typedef struct dns_dns64 dns_dns64_t;
|
||||
typedef ISC_LIST(dns_dns64_t) dns_dns64list_t;
|
||||
typedef struct dns_dnsseckey dns_dnsseckey_t;
|
||||
typedef ISC_LIST(dns_dnsseckey_t) dns_dnsseckeylist_t;
|
||||
typedef struct dns_dumpctx dns_dumpctx_t;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: view.h,v 1.127 2010/09/24 05:09:03 marka Exp $ */
|
||||
/* $Id: view.h,v 1.128 2010/12/08 02:46:16 marka Exp $ */
|
||||
|
||||
#ifndef DNS_VIEW_H
|
||||
#define DNS_VIEW_H 1
|
||||
|
|
@ -158,6 +158,8 @@ struct dns_view {
|
|||
isc_uint16_t maxudp;
|
||||
dns_v4_aaaa_t v4_aaaa;
|
||||
dns_acl_t * v4_aaaa_acl;
|
||||
dns_dns64list_t dns64;
|
||||
unsigned int dns64cnt;
|
||||
|
||||
/*
|
||||
* Configurable data for server use only,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: view.c,v 1.170 2010/09/24 05:09:03 marka Exp $ */
|
||||
/* $Id: view.c,v 1.171 2010/12/08 02:46:16 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
#include <dns/cache.h>
|
||||
#include <dns/db.h>
|
||||
#include <dns/dlz.h>
|
||||
#include <dns/dns64.h>
|
||||
#include <dns/dnssec.h>
|
||||
#include <dns/events.h>
|
||||
#include <dns/forward.h>
|
||||
|
|
@ -145,6 +146,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||
view->resstats = NULL;
|
||||
view->resquerystats = NULL;
|
||||
view->cacheshared = ISC_FALSE;
|
||||
ISC_LIST_INIT(view->dns64);
|
||||
view->dns64cnt = 0;
|
||||
|
||||
/*
|
||||
* Initialize configuration data with default values.
|
||||
|
|
@ -256,6 +259,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||
|
||||
static inline void
|
||||
destroy(dns_view_t *view) {
|
||||
dns_dns64_t *dns64;
|
||||
|
||||
REQUIRE(!ISC_LINK_LINKED(view, link));
|
||||
REQUIRE(isc_refcount_current(&view->references) == 0);
|
||||
REQUIRE(view->weakrefs == 0);
|
||||
|
|
@ -373,6 +378,12 @@ destroy(dns_view_t *view) {
|
|||
dns_stats_detach(&view->resquerystats);
|
||||
if (view->secroots_priv != NULL)
|
||||
dns_keytable_detach(&view->secroots_priv);
|
||||
for (dns64 = ISC_LIST_HEAD(view->dns64);
|
||||
dns64 != NULL;
|
||||
dns64 = ISC_LIST_HEAD(view->dns64)) {
|
||||
dns_dns64_unlink(&view->dns64, dns64);
|
||||
dns_dns64_destroy(&dns64);
|
||||
}
|
||||
#ifdef BIND9
|
||||
if (view->managed_keys != NULL)
|
||||
dns_zone_detach(&view->managed_keys);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: mem.c,v 1.159 2010/08/11 23:46:42 tbox Exp $ */
|
||||
/* $Id: mem.c,v 1.160 2010/12/08 02:46:16 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -1273,7 +1273,7 @@ isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
|
|||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
|
||||
if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0)
|
||||
return (isc_mem_allocate((isc_mem_t *)ctx, size));
|
||||
return (isc__mem_allocate(ctx0, size FLARG_PASS));
|
||||
|
||||
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: namedconf.c,v 1.123 2010/08/11 18:14:20 each Exp $ */
|
||||
/* $Id: namedconf.c,v 1.124 2010/12/08 02:46:17 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
|
|
@ -984,6 +984,31 @@ static cfg_type_t cfg_type_lookaside = {
|
|||
&cfg_rep_tuple, lookaside_fields
|
||||
};
|
||||
|
||||
/*
|
||||
* DNS64.
|
||||
*/
|
||||
static cfg_clausedef_t
|
||||
dns64_clauses[] = {
|
||||
{ "clients", &cfg_type_bracketed_aml, 0 },
|
||||
{ "mapped", &cfg_type_bracketed_aml, 0 },
|
||||
{ "exclude", &cfg_type_bracketed_aml, 0 },
|
||||
{ "suffix", &cfg_type_netaddr6, 0 },
|
||||
{ "recursive-only", &cfg_type_boolean, 0 },
|
||||
{ "break-dnssec", &cfg_type_boolean, 0 },
|
||||
{ NULL, NULL, 0 },
|
||||
};
|
||||
|
||||
static cfg_clausedef_t *
|
||||
dns64_clausesets[] = {
|
||||
dns64_clauses,
|
||||
NULL
|
||||
};
|
||||
|
||||
static cfg_type_t cfg_type_dns64 = {
|
||||
"dns64", cfg_parse_netprefix_map, cfg_print_map, cfg_doc_map,
|
||||
&cfg_rep_map, dns64_clausesets
|
||||
};
|
||||
|
||||
/*%
|
||||
* Clauses that can be found within the 'view' statement,
|
||||
* with defaults in the 'options' statement.
|
||||
|
|
@ -1013,6 +1038,7 @@ view_clauses[] = {
|
|||
{ "disable-algorithms", &cfg_type_disablealgorithm,
|
||||
CFG_CLAUSEFLAG_MULTI },
|
||||
{ "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI },
|
||||
{ "dns64", &cfg_type_dns64, CFG_CLAUSEFLAG_MULTI },
|
||||
{ "dnssec-accept-expired", &cfg_type_boolean, 0 },
|
||||
{ "dnssec-enable", &cfg_type_boolean, 0 },
|
||||
{ "dnssec-lookaside", &cfg_type_lookaside, CFG_CLAUSEFLAG_MULTI },
|
||||
|
|
|
|||
Loading…
Reference in a new issue