mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-13 20:30:00 -04:00
3306. [bug] Improve DNS64 reverse zone performance. [RT #28563]
3305. [func] Add wire format lookup method to sdb. [RT #28563]
This commit is contained in:
parent
e3a1a68c1b
commit
74ce4de82e
6 changed files with 234 additions and 106 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,3 +1,7 @@
|
|||
3306. [bug] Improve DNS64 reverse zone performance. [RT #28563]
|
||||
|
||||
3305. [func] Add wire format lookup method to sdb. [RT #28563]
|
||||
|
||||
3304. [bug] Use hmctx, not mctx when freeing rbtdb->heaps. [RT #28571]
|
||||
|
||||
3303. [bug] named could die when reloading. [RT #28606]
|
||||
|
|
|
|||
|
|
@ -69,35 +69,79 @@ static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL };
|
|||
static builtin_t dns64_builtin = { do_dns64_lookup, NULL, NULL };
|
||||
|
||||
static dns_sdbimplementation_t *builtin_impl;
|
||||
static dns_sdbimplementation_t *dns64_impl;
|
||||
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
static const char HEX[] = "0123456789ABCDEF";
|
||||
/*
|
||||
* Pre computed HEX * 16 or 1 table.
|
||||
*/
|
||||
static const unsigned char hex16[256] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*00*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*20*/
|
||||
0, 16, 32, 48, 64, 80, 96,112,128,144, 1, 1, 1, 1, 1, 1, /*30*/
|
||||
1,160,176,192,208,224,240, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*50*/
|
||||
1,160,176,192,208,224,240, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*60*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*A0*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*B0*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*C0*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*D0*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*E0*/
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /*F0*/
|
||||
};
|
||||
|
||||
const unsigned char decimal[] = "0123456789";
|
||||
|
||||
static size_t
|
||||
dns64_rdata(unsigned char *v, size_t start, unsigned char *rdata) {
|
||||
size_t i, j = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
unsigned char c = v[start++];
|
||||
if (start == 7)
|
||||
start++;
|
||||
if (c > 99) {
|
||||
rdata[j++] = 3;
|
||||
rdata[j++] = decimal[c/100]; c = c % 100;
|
||||
rdata[j++] = decimal[c/10]; c = c % 10;
|
||||
rdata[j++] = decimal[c];
|
||||
} else if (c > 9) {
|
||||
rdata[j++] = 2;
|
||||
rdata[j++] = decimal[c/10]; c = c % 10;
|
||||
rdata[j++] = decimal[c];
|
||||
} else {
|
||||
rdata[j++] = 1;
|
||||
rdata[j++] = decimal[c];
|
||||
}
|
||||
}
|
||||
memcpy(&rdata[j], "\07in-addr\04arpa", 14);
|
||||
return (j + 14);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) {
|
||||
size_t zlen, nlen, j;
|
||||
const char *s;
|
||||
unsigned char v[16];
|
||||
dns64_cname(const dns_name_t *zone, const dns_name_t *name,
|
||||
dns_sdblookup_t *lookup)
|
||||
{
|
||||
size_t zlen, nlen, j, len;
|
||||
unsigned char v[16], n;
|
||||
unsigned int i;
|
||||
char reverse[sizeof("123.123.123.123.in-addr.arpa.")];
|
||||
unsigned char rdata[sizeof("123.123.123.123.in-addr.arpa.")];
|
||||
unsigned char *ndata;
|
||||
|
||||
/*
|
||||
* The sum the length of the relative name and the length of the zone
|
||||
* name for a IPv6 reverse lookup comes to 71.
|
||||
* The combined length of the zone and name is 74.
|
||||
*
|
||||
* The reverse of 2001::10.0.0.1 (dns64 2001::/96) has a zone of
|
||||
* "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.2.ip6.arpa"
|
||||
* and a name of "1.0.0.0.0.0.a.0". The sum of the lengths of these
|
||||
* two strings is 71.
|
||||
* The minimum zone length is 10 ((3)ip6(4)arpa(0)).
|
||||
*
|
||||
* The minimum length for a ip6.arpa zone name is 8.
|
||||
*
|
||||
* The length of name should always be odd as we are expecting
|
||||
* The length of name should always be even as we are expecting
|
||||
* a series of nibbles.
|
||||
*/
|
||||
zlen = strlen(zone);
|
||||
nlen = strlen(name);
|
||||
if ((zlen + nlen) > 71U || zlen < 8U || (nlen % 2) != 1U)
|
||||
zlen = zone->length;
|
||||
nlen = name->length;
|
||||
if ((zlen + nlen) > 74U || zlen < 10U || (nlen % 2) != 0U)
|
||||
return (ISC_R_NOTFOUND);
|
||||
|
||||
/*
|
||||
|
|
@ -116,25 +160,20 @@ dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) {
|
|||
* are byte aligned and we correctly return ISC_R_NOTFOUND or
|
||||
* ISC_R_SUCCESS. We will not generate a CNAME in this case.
|
||||
*/
|
||||
i = (nlen % 4) == 1U ? 1 : 0;
|
||||
ndata = name->ndata;
|
||||
i = (nlen % 4) == 2U ? 1 : 0;
|
||||
j = nlen;
|
||||
memset(v, 0, sizeof(v));
|
||||
while (j >= 1U) {
|
||||
while (j != 0) {
|
||||
INSIST((i/2) < sizeof(v));
|
||||
if (j > 1U && name[1] != '.')
|
||||
if (ndata[0] != 1)
|
||||
return (ISC_R_NOTFOUND);
|
||||
v[i/2] >>= 4;
|
||||
if ((s = strchr(hex, name[0])) != NULL)
|
||||
v[i/2] |= (s - hex) << 4;
|
||||
else if ((s = strchr(HEX, name[0])) != NULL)
|
||||
v[i/2] |= (s - HEX) << 4;
|
||||
else
|
||||
n = hex16[ndata[1]&0xff];
|
||||
if (n == 1)
|
||||
return (ISC_R_NOTFOUND);
|
||||
if (j > 1U)
|
||||
j -= 2;
|
||||
else
|
||||
j -= 1;
|
||||
name += 2;
|
||||
v[i/2] = n | (v[i/2]>>4);
|
||||
j -= 2;
|
||||
ndata += 2;
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
@ -144,90 +183,91 @@ dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) {
|
|||
* it corresponds to a empty node in the zone or there should be
|
||||
* a CNAME.
|
||||
*/
|
||||
#define ZLEN(x) (10 + (x)/2)
|
||||
switch (zlen) {
|
||||
case 24: /* prefix len 32 */
|
||||
/*
|
||||
* If the total length is not 71 then this is a empty node
|
||||
* so return success.
|
||||
*/
|
||||
if (nlen + zlen != 71U)
|
||||
return (ISC_R_SUCCESS);
|
||||
snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
|
||||
v[8], v[9], v[10], v[11]);
|
||||
break;
|
||||
case 28: /* prefix len 40 */
|
||||
case ZLEN(32): /* prefix len 32 */
|
||||
/*
|
||||
* The nibbles that map to this byte must be zero for 'name'
|
||||
* to exist in the zone.
|
||||
*/
|
||||
if (nlen > 11U && v[nlen/4 - 3] != 0)
|
||||
if (nlen > 16U && v[(nlen-1)/4 - 4] != 0)
|
||||
return (ISC_R_NOTFOUND);
|
||||
/*
|
||||
* If the total length is not 71 then this is a empty node
|
||||
* If the total length is not 74 then this is a empty node
|
||||
* so return success.
|
||||
*/
|
||||
if (nlen + zlen != 71U)
|
||||
if (nlen + zlen != 74U)
|
||||
return (ISC_R_SUCCESS);
|
||||
snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
|
||||
v[6], v[8], v[9], v[10]);
|
||||
len = dns64_rdata(v, 8, rdata);
|
||||
break;
|
||||
case 32: /* prefix len 48 */
|
||||
case ZLEN(40): /* prefix len 40 */
|
||||
/*
|
||||
* The nibbles that map to this byte must be zero for 'name'
|
||||
* to exist in the zone.
|
||||
*/
|
||||
if (nlen > 7U && v[nlen/4 - 2] != 0)
|
||||
if (nlen > 12U && v[(nlen-1)/4 - 3] != 0)
|
||||
return (ISC_R_NOTFOUND);
|
||||
/*
|
||||
* If the total length is not 71 then this is a empty node
|
||||
* If the total length is not 74 then this is a empty node
|
||||
* so return success.
|
||||
*/
|
||||
if (nlen + zlen != 71U)
|
||||
if (nlen + zlen != 74U)
|
||||
return (ISC_R_SUCCESS);
|
||||
snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
|
||||
v[5], v[6], v[8], v[9]);
|
||||
len = dns64_rdata(v, 6, rdata);
|
||||
break;
|
||||
case 36: /* prefix len 56 */
|
||||
case ZLEN(48): /* prefix len 48 */
|
||||
/*
|
||||
* The nibbles that map to this byte must be zero for 'name'
|
||||
* to exist in the zone.
|
||||
*/
|
||||
if (nlen > 3U && v[nlen/4 - 1] != 0)
|
||||
if (nlen > 8U && v[(nlen-1)/4 - 2] != 0)
|
||||
return (ISC_R_NOTFOUND);
|
||||
/*
|
||||
* If the total length is not 71 then this is a empty node
|
||||
* If the total length is not 74 then this is a empty node
|
||||
* so return success.
|
||||
*/
|
||||
if (nlen + zlen != 71U)
|
||||
if (nlen + zlen != 74U)
|
||||
return (ISC_R_SUCCESS);
|
||||
snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
|
||||
v[4], v[5], v[6], v[8]);
|
||||
len = dns64_rdata(v, 5, rdata);
|
||||
break;
|
||||
case 40: /* prefix len 64 */
|
||||
case ZLEN(56): /* prefix len 56 */
|
||||
/*
|
||||
* The nibbles that map to this byte must be zero for 'name'
|
||||
* to exist in the zone.
|
||||
*/
|
||||
if (v[nlen/4] != 0)
|
||||
if (nlen > 4U && v[(nlen-1)/4 - 1] != 0)
|
||||
return (ISC_R_NOTFOUND);
|
||||
/*
|
||||
* If the total length is not 71 then this is a empty node
|
||||
* If the total length is not 74 then this is a empty node
|
||||
* so return success.
|
||||
*/
|
||||
if (nlen + zlen != 71U)
|
||||
if (nlen + zlen != 74U)
|
||||
return (ISC_R_SUCCESS);
|
||||
snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
|
||||
v[3], v[4], v[5], v[6]);
|
||||
len = dns64_rdata(v, 4, rdata);
|
||||
break;
|
||||
case 56: /* prefix len 96 */
|
||||
case ZLEN(64): /* prefix len 64 */
|
||||
/*
|
||||
* If the total length is not 71 then this is a empty node
|
||||
* The nibbles that map to this byte must be zero for 'name'
|
||||
* to exist in the zone.
|
||||
*/
|
||||
if (v[(nlen-1)/4] != 0)
|
||||
return (ISC_R_NOTFOUND);
|
||||
/*
|
||||
* If the total length is not 74 then this is a empty node
|
||||
* so return success.
|
||||
*/
|
||||
if (nlen + zlen != 71U)
|
||||
if (nlen + zlen != 74U)
|
||||
return (ISC_R_SUCCESS);
|
||||
snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
|
||||
v[0], v[1], v[2], v[3]);
|
||||
len = dns64_rdata(v, 3, rdata);
|
||||
break;
|
||||
case ZLEN(96): /* prefix len 96 */
|
||||
/*
|
||||
* If the total length is not 74 then this is a empty node
|
||||
* so return success.
|
||||
*/
|
||||
if (nlen + zlen != 74U)
|
||||
return (ISC_R_SUCCESS);
|
||||
len = dns64_rdata(v, 0, rdata);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
|
|
@ -236,7 +276,7 @@ dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) {
|
|||
*/
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
return (dns_sdb_putrr(lookup, "CNAME", 600, reverse));
|
||||
return (dns_sdb_putrdata(lookup, dns_rdatatype_cname, 600, rdata, len));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
@ -252,12 +292,26 @@ builtin_lookup(const char *zone, const char *name, void *dbdata,
|
|||
|
||||
if (strcmp(name, "@") == 0)
|
||||
return (b->do_lookup(lookup));
|
||||
else if (b->do_lookup == do_dns64_lookup)
|
||||
return (dns64_cname(zone, name, lookup));
|
||||
else
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dns64_lookup(const dns_name_t *zone, const dns_name_t *name, void *dbdata,
|
||||
dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods,
|
||||
dns_clientinfo_t *clientinfo)
|
||||
{
|
||||
builtin_t *b = (builtin_t *) dbdata;
|
||||
|
||||
UNUSED(methods);
|
||||
UNUSED(clientinfo);
|
||||
|
||||
if (name->labels == 0 && name->length == 0)
|
||||
return (b->do_lookup(lookup));
|
||||
else
|
||||
return (dns64_cname(zone, name, lookup));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
put_txt(dns_sdblookup_t *lookup, const char *text) {
|
||||
unsigned char buf[256];
|
||||
|
|
@ -486,7 +540,17 @@ static dns_sdbmethods_t builtin_methods = {
|
|||
builtin_authority,
|
||||
NULL, /* allnodes */
|
||||
builtin_create,
|
||||
builtin_destroy
|
||||
builtin_destroy,
|
||||
NULL
|
||||
};
|
||||
|
||||
static dns_sdbmethods_t dns64_methods = {
|
||||
NULL,
|
||||
builtin_authority,
|
||||
NULL, /* allnodes */
|
||||
builtin_create,
|
||||
builtin_destroy,
|
||||
dns64_lookup,
|
||||
};
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -496,11 +560,17 @@ ns_builtin_init(void) {
|
|||
DNS_SDBFLAG_RELATIVERDATA,
|
||||
ns_g_mctx, &builtin_impl)
|
||||
== ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(dns_sdb_register("_dns64", &dns64_methods, NULL,
|
||||
DNS_SDBFLAG_RELATIVEOWNER |
|
||||
DNS_SDBFLAG_RELATIVERDATA |
|
||||
DNS_SDBFLAG_DNS64,
|
||||
ns_g_mctx, &dns64_impl)
|
||||
== ISC_R_SUCCESS);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
ns_builtin_deinit(void) {
|
||||
dns_sdb_unregister(&builtin_impl);
|
||||
dns_sdb_unregister(&dns64_impl);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1368,7 +1368,7 @@ dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na,
|
|||
{
|
||||
char *cp;
|
||||
char reverse[48+sizeof("ip6.arpa.")];
|
||||
const char *dns64_dbtype[4] = { "_builtin", "dns64", ".", "." };
|
||||
const char *dns64_dbtype[4] = { "_dns64", "dns64", ".", "." };
|
||||
const char *sep = ": view ";
|
||||
const char *viewname = view->name;
|
||||
const unsigned char *s6;
|
||||
|
|
|
|||
|
|
@ -1264,6 +1264,23 @@ do
|
|||
status=`expr $status + $ret`
|
||||
done
|
||||
|
||||
rev=`$ARPANAME 2001:aaaa::10.0.0.1`
|
||||
regex='..\(.*.IP6.ARPA\)'
|
||||
rev=`expr "${rev}" : "${regex}"`
|
||||
fin=`expr "${rev}" : "............${regex}"`
|
||||
while test "${rev}" != "${fin}"
|
||||
do
|
||||
ret=0
|
||||
echo "I: checking $rev ($n)"
|
||||
$DIG $DIGOPTS $rev ptr @10.53.0.2 > dig.out.ns2.test$n || ret=1
|
||||
grep -i "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
|
||||
grep -i "ANSWER: 0," 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`
|
||||
rev=`expr "${rev}" : "${regex}"`
|
||||
done
|
||||
|
||||
echo "I: checking dns64-server and dns64-contact ($n)"
|
||||
$DIG $DIGOPTS soa 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.a.a.a.1.0.0.2.ip6.arpa @10.53.0.2 > dig.out.ns2.test$n || ret=1
|
||||
grep "SOA.dns64.example.net..hostmaster.example.net." dig.out.ns2.test$n > /dev/null || ret=1
|
||||
|
|
|
|||
|
|
@ -62,7 +62,12 @@ typedef isc_result_t
|
|||
dns_sdblookup_t *lookup,
|
||||
dns_clientinfomethods_t *methods,
|
||||
dns_clientinfo_t *clientinfo);
|
||||
|
||||
typedef isc_result_t
|
||||
(*dns_sdblookup2func_t)(const dns_name_t *zone, const dns_name_t *name,
|
||||
void *dbdata, dns_sdblookup_t *lookup,
|
||||
dns_clientinfomethods_t *methods,
|
||||
dns_clientinfo_t *clientinfo);
|
||||
|
||||
typedef isc_result_t
|
||||
(*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *);
|
||||
|
||||
|
|
@ -84,6 +89,7 @@ typedef struct dns_sdbmethods {
|
|||
dns_sdballnodesfunc_t allnodes;
|
||||
dns_sdbcreatefunc_t create;
|
||||
dns_sdbdestroyfunc_t destroy;
|
||||
dns_sdblookup2func_t lookup2;
|
||||
} dns_sdbmethods_t;
|
||||
|
||||
/***
|
||||
|
|
@ -95,6 +101,7 @@ ISC_LANG_BEGINDECLS
|
|||
#define DNS_SDBFLAG_RELATIVEOWNER 0x00000001U
|
||||
#define DNS_SDBFLAG_RELATIVERDATA 0x00000002U
|
||||
#define DNS_SDBFLAG_THREADSAFE 0x00000004U
|
||||
#define DNS_SDBFLAG_DNS64 0x00000008U
|
||||
|
||||
isc_result_t
|
||||
dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods,
|
||||
|
|
|
|||
|
|
@ -216,12 +216,13 @@ dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods,
|
|||
|
||||
REQUIRE(drivername != NULL);
|
||||
REQUIRE(methods != NULL);
|
||||
REQUIRE(methods->lookup != NULL);
|
||||
REQUIRE(methods->lookup != NULL || methods->lookup2 != NULL);
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(sdbimp != NULL && *sdbimp == NULL);
|
||||
REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER |
|
||||
DNS_SDBFLAG_RELATIVERDATA |
|
||||
DNS_SDBFLAG_THREADSAFE)) == 0);
|
||||
DNS_SDBFLAG_THREADSAFE|
|
||||
DNS_SDBFLAG_DNS64)) == 0);
|
||||
|
||||
imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t));
|
||||
if (imp == NULL)
|
||||
|
|
@ -280,8 +281,9 @@ initial_size(unsigned int len) {
|
|||
}
|
||||
|
||||
isc_result_t
|
||||
dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, dns_ttl_t ttl,
|
||||
const unsigned char *rdatap, unsigned int rdlen)
|
||||
dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval,
|
||||
dns_ttl_t ttl, const unsigned char *rdatap,
|
||||
unsigned int rdlen)
|
||||
{
|
||||
dns_rdatalist_t *rdatalist;
|
||||
dns_rdata_t *rdata;
|
||||
|
|
@ -338,7 +340,6 @@ dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, dns_ttl_t ttl
|
|||
return (result);
|
||||
}
|
||||
|
||||
|
||||
isc_result_t
|
||||
dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
|
||||
const char *data)
|
||||
|
|
@ -738,6 +739,8 @@ findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
|
|||
char namestr[DNS_NAME_MAXTEXT + 1];
|
||||
isc_boolean_t isorigin;
|
||||
dns_sdbimplementation_t *imp;
|
||||
dns_name_t relname;
|
||||
unsigned int labels;
|
||||
|
||||
REQUIRE(VALID_SDB(sdb));
|
||||
REQUIRE(create == ISC_FALSE);
|
||||
|
|
@ -748,34 +751,47 @@ findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
|
|||
|
||||
imp = sdb->implementation;
|
||||
|
||||
isc_buffer_init(&b, namestr, sizeof(namestr));
|
||||
if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
|
||||
dns_name_t relname;
|
||||
unsigned int labels;
|
||||
isorigin = dns_name_equal(name, &sdb->common.origin);
|
||||
|
||||
labels = dns_name_countlabels(name) -
|
||||
dns_name_countlabels(&db->origin);
|
||||
dns_name_init(&relname, NULL);
|
||||
dns_name_getlabelsequence(name, 0, labels, &relname);
|
||||
result = dns_name_totext(&relname, ISC_TRUE, &b);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
if (imp->methods->lookup2 != NULL) {
|
||||
if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
|
||||
labels = dns_name_countlabels(name) -
|
||||
dns_name_countlabels(&db->origin);
|
||||
dns_name_init(&relname, NULL);
|
||||
dns_name_getlabelsequence(name, 0, labels, &relname);
|
||||
name = &relname;
|
||||
}
|
||||
} else {
|
||||
result = dns_name_totext(name, ISC_TRUE, &b);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
isc_buffer_init(&b, namestr, sizeof(namestr));
|
||||
if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) {
|
||||
|
||||
labels = dns_name_countlabels(name) -
|
||||
dns_name_countlabels(&db->origin);
|
||||
dns_name_init(&relname, NULL);
|
||||
dns_name_getlabelsequence(name, 0, labels, &relname);
|
||||
result = dns_name_totext(&relname, ISC_TRUE, &b);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
} else {
|
||||
result = dns_name_totext(name, ISC_TRUE, &b);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
}
|
||||
isc_buffer_putuint8(&b, 0);
|
||||
}
|
||||
isc_buffer_putuint8(&b, 0);
|
||||
|
||||
result = createnode(sdb, &node);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
isorigin = dns_name_equal(name, &sdb->common.origin);
|
||||
|
||||
MAYBE_LOCK(sdb);
|
||||
result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata,
|
||||
node, methods, clientinfo);
|
||||
if (imp->methods->lookup2 != NULL)
|
||||
result = imp->methods->lookup2(&sdb->common.origin, name,
|
||||
sdb->dbdata, node, methods,
|
||||
clientinfo);
|
||||
else
|
||||
result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata,
|
||||
node, methods, clientinfo);
|
||||
MAYBE_UNLOCK(sdb);
|
||||
if (result != ISC_R_SUCCESS &&
|
||||
!(result == ISC_R_NOTFOUND &&
|
||||
|
|
@ -814,13 +830,13 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
|||
unsigned int nlabels, olabels;
|
||||
isc_result_t result;
|
||||
unsigned int i;
|
||||
unsigned int flags;
|
||||
|
||||
REQUIRE(VALID_SDB(sdb));
|
||||
REQUIRE(nodep == NULL || *nodep == NULL);
|
||||
REQUIRE(version == NULL || version == (void *) &dummy);
|
||||
|
||||
UNUSED(options);
|
||||
UNUSED(sdb);
|
||||
|
||||
if (!dns_name_issubdomain(name, &db->origin))
|
||||
return (DNS_R_NXDOMAIN);
|
||||
|
|
@ -837,8 +853,9 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
|||
}
|
||||
|
||||
result = DNS_R_NXDOMAIN;
|
||||
|
||||
for (i = olabels; i <= nlabels; i++) {
|
||||
flags = sdb->implementation->flags;
|
||||
i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels;
|
||||
for (; i <= nlabels; i++) {
|
||||
/*
|
||||
* Look up the next label.
|
||||
*/
|
||||
|
|
@ -857,6 +874,18 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
|||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
/*
|
||||
* DNS64 zone's don't have DNAME or NS records.
|
||||
*/
|
||||
if ((flags & DNS_SDBFLAG_DNS64) != 0)
|
||||
goto skip;
|
||||
|
||||
/*
|
||||
* DNS64 zone's don't have DNAME or NS records.
|
||||
*/
|
||||
if ((flags & DNS_SDBFLAG_DNS64) != 0)
|
||||
goto skip;
|
||||
|
||||
/*
|
||||
* Look for a DNAME at the current label, unless this is
|
||||
* the qname.
|
||||
|
|
@ -906,6 +935,7 @@ findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
|||
continue;
|
||||
}
|
||||
|
||||
skip:
|
||||
/*
|
||||
* If we're looking for ANY, we're done.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue