mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
fix: usr: Fix a bug in the static-stub implementation
Static-stub addresses and addresses from other sources were being mixed together, resulting in static-stub queries going to addresses not specified in the configuration, or alternatively, static-stub addresses being used instead of the correct server addresses. Closes #4850 Merge branch '4850-add-an-additional-class-of-names-to-adb' into 'main' See merge request isc-projects/bind9!9314
This commit is contained in:
@@ -265,7 +265,7 @@ ISC_REFCOUNT_DECL(dns_adbentry);
|
|||||||
* Internal functions (and prototypes).
|
* Internal functions (and prototypes).
|
||||||
*/
|
*/
|
||||||
static dns_adbname_t *
|
static dns_adbname_t *
|
||||||
new_adbname(dns_adb_t *adb, const dns_name_t *, bool start_at_zone);
|
new_adbname(dns_adb_t *adb, const dns_name_t *, unsigned int flags);
|
||||||
static void
|
static void
|
||||||
destroy_adbname(dns_adbname_t *);
|
destroy_adbname(dns_adbname_t *);
|
||||||
static bool
|
static bool
|
||||||
@@ -296,7 +296,7 @@ static void
|
|||||||
purge_stale_names(dns_adb_t *adb, isc_stdtime_t now);
|
purge_stale_names(dns_adb_t *adb, isc_stdtime_t now);
|
||||||
static dns_adbname_t *
|
static dns_adbname_t *
|
||||||
get_attached_and_locked_name(dns_adb_t *, const dns_name_t *,
|
get_attached_and_locked_name(dns_adb_t *, const dns_name_t *,
|
||||||
bool start_at_zone, isc_stdtime_t now);
|
unsigned int flags, isc_stdtime_t now);
|
||||||
static void
|
static void
|
||||||
purge_stale_entries(dns_adb_t *adb, isc_stdtime_t now);
|
purge_stale_entries(dns_adb_t *adb, isc_stdtime_t now);
|
||||||
static dns_adbentry_t *
|
static dns_adbentry_t *
|
||||||
@@ -409,9 +409,12 @@ enum {
|
|||||||
#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
|
#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
|
||||||
#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) != 0)
|
#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) != 0)
|
||||||
#define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) != 0)
|
#define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) != 0)
|
||||||
|
#define FIND_STATICSTUB(fn) (((fn)->options & DNS_ADBFIND_STATICSTUB) != 0)
|
||||||
#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
|
#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
|
||||||
#define FIND_NOFETCH(fn) (((fn)->options & DNS_ADBFIND_NOFETCH) != 0)
|
#define FIND_NOFETCH(fn) (((fn)->options & DNS_ADBFIND_NOFETCH) != 0)
|
||||||
|
|
||||||
|
#define ADBNAME_FLAGS_MASK (DNS_ADBFIND_STARTATZONE | DNS_ADBFIND_STATICSTUB)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are currently used on simple unsigned ints, so they are
|
* These are currently used on simple unsigned ints, so they are
|
||||||
* not really associated with any particular type.
|
* not really associated with any particular type.
|
||||||
@@ -951,7 +954,7 @@ clean_finds_at_name(dns_adbname_t *name, dns_adbstatus_t astat,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static dns_adbname_t *
|
static dns_adbname_t *
|
||||||
new_adbname(dns_adb_t *adb, const dns_name_t *dnsname, bool start_at_zone) {
|
new_adbname(dns_adb_t *adb, const dns_name_t *dnsname, unsigned int flags) {
|
||||||
dns_adbname_t *name = NULL;
|
dns_adbname_t *name = NULL;
|
||||||
|
|
||||||
name = isc_mem_get(adb->mctx, sizeof(*name));
|
name = isc_mem_get(adb->mctx, sizeof(*name));
|
||||||
@@ -966,6 +969,7 @@ new_adbname(dns_adb_t *adb, const dns_name_t *dnsname, bool start_at_zone) {
|
|||||||
.v6 = ISC_LIST_INITIALIZER,
|
.v6 = ISC_LIST_INITIALIZER,
|
||||||
.finds = ISC_LIST_INITIALIZER,
|
.finds = ISC_LIST_INITIALIZER,
|
||||||
.link = ISC_LINK_INITIALIZER,
|
.link = ISC_LINK_INITIALIZER,
|
||||||
|
.flags = flags & ADBNAME_FLAGS_MASK,
|
||||||
.magic = DNS_ADBNAME_MAGIC,
|
.magic = DNS_ADBNAME_MAGIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -981,10 +985,6 @@ new_adbname(dns_adb_t *adb, const dns_name_t *dnsname, bool start_at_zone) {
|
|||||||
dns_name_copy(dnsname, name->name);
|
dns_name_copy(dnsname, name->name);
|
||||||
dns_name_init(&name->target, NULL);
|
dns_name_init(&name->target, NULL);
|
||||||
|
|
||||||
if (start_at_zone) {
|
|
||||||
name->flags |= DNS_ADBFIND_STARTATZONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
inc_adbstats(adb, dns_adbstats_namescnt);
|
inc_adbstats(adb, dns_adbstats_namescnt);
|
||||||
return (name);
|
return (name);
|
||||||
}
|
}
|
||||||
@@ -1235,8 +1235,8 @@ match_adbname(void *node, const void *key) {
|
|||||||
const dns_adbname_t *adbname0 = node;
|
const dns_adbname_t *adbname0 = node;
|
||||||
const dns_adbname_t *adbname1 = key;
|
const dns_adbname_t *adbname1 = key;
|
||||||
|
|
||||||
if ((adbname0->flags & DNS_ADBFIND_STARTATZONE) !=
|
if ((adbname0->flags & ADBNAME_FLAGS_MASK) !=
|
||||||
(adbname1->flags & DNS_ADBFIND_STARTATZONE))
|
(adbname1->flags & ADBNAME_FLAGS_MASK))
|
||||||
{
|
{
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@@ -1247,12 +1247,12 @@ match_adbname(void *node, const void *key) {
|
|||||||
static uint32_t
|
static uint32_t
|
||||||
hash_adbname(const dns_adbname_t *adbname) {
|
hash_adbname(const dns_adbname_t *adbname) {
|
||||||
isc_hash32_t hash;
|
isc_hash32_t hash;
|
||||||
bool start_at_zone = adbname->flags & DNS_ADBFIND_STARTATZONE;
|
unsigned int flags = adbname->flags & ADBNAME_FLAGS_MASK;
|
||||||
|
|
||||||
isc_hash32_init(&hash);
|
isc_hash32_init(&hash);
|
||||||
isc_hash32_hash(&hash, adbname->name->ndata, adbname->name->length,
|
isc_hash32_hash(&hash, adbname->name->ndata, adbname->name->length,
|
||||||
false);
|
false);
|
||||||
isc_hash32_hash(&hash, &start_at_zone, sizeof(start_at_zone), true);
|
isc_hash32_hash(&hash, &flags, sizeof(flags), true);
|
||||||
return (isc_hash32_finalize(&hash));
|
return (isc_hash32_finalize(&hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1261,14 +1261,14 @@ hash_adbname(const dns_adbname_t *adbname) {
|
|||||||
*/
|
*/
|
||||||
static dns_adbname_t *
|
static dns_adbname_t *
|
||||||
get_attached_and_locked_name(dns_adb_t *adb, const dns_name_t *name,
|
get_attached_and_locked_name(dns_adb_t *adb, const dns_name_t *name,
|
||||||
bool start_at_zone, isc_stdtime_t now) {
|
unsigned int flags, isc_stdtime_t now) {
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_adbname_t *adbname = NULL;
|
dns_adbname_t *adbname = NULL;
|
||||||
isc_time_t timenow;
|
isc_time_t timenow;
|
||||||
isc_stdtime_t last_update;
|
isc_stdtime_t last_update;
|
||||||
dns_adbname_t key = {
|
dns_adbname_t key = {
|
||||||
.name = UNCONST(name),
|
.name = UNCONST(name),
|
||||||
.flags = (start_at_zone) ? DNS_ADBFIND_STARTATZONE : 0,
|
.flags = flags & ADBNAME_FLAGS_MASK,
|
||||||
};
|
};
|
||||||
uint32_t hashval = hash_adbname(&key);
|
uint32_t hashval = hash_adbname(&key);
|
||||||
isc_rwlocktype_t locktype = isc_rwlocktype_read;
|
isc_rwlocktype_t locktype = isc_rwlocktype_read;
|
||||||
@@ -1294,7 +1294,7 @@ get_attached_and_locked_name(dns_adb_t *adb, const dns_name_t *name,
|
|||||||
UPGRADELOCK(&adb->names_lock, locktype);
|
UPGRADELOCK(&adb->names_lock, locktype);
|
||||||
|
|
||||||
/* Allocate a new name and add it to the hash table. */
|
/* Allocate a new name and add it to the hash table. */
|
||||||
adbname = new_adbname(adb, name, start_at_zone);
|
adbname = new_adbname(adb, name, key.flags);
|
||||||
|
|
||||||
void *found = NULL;
|
void *found = NULL;
|
||||||
result = isc_hashmap_add(adb->names, hashval, match_adbname,
|
result = isc_hashmap_add(adb->names, hashval, match_adbname,
|
||||||
@@ -1959,6 +1959,13 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
|
|||||||
now = isc_stdtime_now();
|
now = isc_stdtime_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If STATICSTUB is set we always want to have STARTATZONE set.
|
||||||
|
*/
|
||||||
|
if (options & DNS_ADBFIND_STATICSTUB) {
|
||||||
|
options |= DNS_ADBFIND_STARTATZONE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember what types of addresses we are interested in.
|
* Remember what types of addresses we are interested in.
|
||||||
*/
|
*/
|
||||||
@@ -1975,8 +1982,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
|
|||||||
|
|
||||||
again:
|
again:
|
||||||
/* Try to see if we know anything about this name at all. */
|
/* Try to see if we know anything about this name at all. */
|
||||||
adbname = get_attached_and_locked_name(adb, name,
|
adbname = get_attached_and_locked_name(adb, name, find->options, now);
|
||||||
FIND_STARTATZONE(find), now);
|
|
||||||
|
|
||||||
if (NAME_DEAD(adbname)) {
|
if (NAME_DEAD(adbname)) {
|
||||||
UNLOCK(&adbname->lock);
|
UNLOCK(&adbname->lock);
|
||||||
@@ -2050,7 +2056,7 @@ again:
|
|||||||
* Any other result, start a fetch for A, then fall
|
* Any other result, start a fetch for A, then fall
|
||||||
* through to AAAA.
|
* through to AAAA.
|
||||||
*/
|
*/
|
||||||
if (!NAME_FETCH_A(adbname)) {
|
if (!NAME_FETCH_A(adbname) && !FIND_STATICSTUB(find)) {
|
||||||
wanted_fetches |= DNS_ADBFIND_INET;
|
wanted_fetches |= DNS_ADBFIND_INET;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -2093,7 +2099,8 @@ again:
|
|||||||
/*
|
/*
|
||||||
* Any other result, start a fetch for AAAA.
|
* Any other result, start a fetch for AAAA.
|
||||||
*/
|
*/
|
||||||
if (!NAME_FETCH_AAAA(adbname)) {
|
if (!NAME_FETCH_AAAA(adbname) && !FIND_STATICSTUB(find))
|
||||||
|
{
|
||||||
wanted_fetches |= DNS_ADBFIND_INET6;
|
wanted_fetches |= DNS_ADBFIND_INET6;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -3391,6 +3398,7 @@ dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) {
|
|||||||
dns_adbname_t *adbname = NULL;
|
dns_adbname_t *adbname = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
bool start_at_zone = false;
|
bool start_at_zone = false;
|
||||||
|
bool static_stub = false;
|
||||||
dns_adbname_t key = { .name = UNCONST(name) };
|
dns_adbname_t key = { .name = UNCONST(name) };
|
||||||
|
|
||||||
REQUIRE(DNS_ADB_VALID(adb));
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
@@ -3403,9 +3411,11 @@ dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) {
|
|||||||
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
again:
|
again:
|
||||||
/*
|
/*
|
||||||
* Delete both entries - without and with DNS_ADBFIND_STARTATZONE set.
|
* Delete all entries - with and without DNS_ADBFIND_STARTATZONE set
|
||||||
|
* and with and without DNS_ADBFIND_STATICSTUB set.
|
||||||
*/
|
*/
|
||||||
key.flags = (start_at_zone) ? DNS_ADBFIND_STARTATZONE : 0;
|
key.flags = ((static_stub) ? DNS_ADBFIND_STATICSTUB : 0) |
|
||||||
|
((start_at_zone) ? DNS_ADBFIND_STARTATZONE : 0);
|
||||||
|
|
||||||
result = isc_hashmap_find(adb->names, hash_adbname(&key), match_adbname,
|
result = isc_hashmap_find(adb->names, hash_adbname(&key), match_adbname,
|
||||||
(void *)&key, (void **)&adbname);
|
(void *)&key, (void **)&adbname);
|
||||||
@@ -3422,6 +3432,10 @@ again:
|
|||||||
start_at_zone = true;
|
start_at_zone = true;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
if (!static_stub) {
|
||||||
|
static_stub = true;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -192,6 +192,10 @@ struct dns_adbfind {
|
|||||||
* Don't perform a fetch even if there are no address records available.
|
* Don't perform a fetch even if there are no address records available.
|
||||||
*/
|
*/
|
||||||
#define DNS_ADBFIND_NOFETCH 0x00000800
|
#define DNS_ADBFIND_NOFETCH 0x00000800
|
||||||
|
/*%
|
||||||
|
* Only look for glue record for static stub.
|
||||||
|
*/
|
||||||
|
#define DNS_ADBFIND_STATICSTUB 0x00001000
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* The answers to queries come back as a list of these.
|
* The answers to queries come back as a list of these.
|
||||||
|
@@ -265,6 +265,7 @@ struct dns_rdataset {
|
|||||||
#define DNS_RDATASETATTR_STALE_WINDOW 0x04000000
|
#define DNS_RDATASETATTR_STALE_WINDOW 0x04000000
|
||||||
#define DNS_RDATASETATTR_STALE_ADDED 0x08000000
|
#define DNS_RDATASETATTR_STALE_ADDED 0x08000000
|
||||||
#define DNS_RDATASETATTR_KEEPCASE 0x10000000
|
#define DNS_RDATASETATTR_KEEPCASE 0x10000000
|
||||||
|
#define DNS_RDATASETATTR_STATICSTUB 0x20000000
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* _OMITDNSSEC:
|
* _OMITDNSSEC:
|
||||||
|
@@ -627,8 +627,9 @@ enum {
|
|||||||
#define BADCOOKIE(a) (((a)->flags & FCTX_ADDRINFO_BADCOOKIE) != 0)
|
#define BADCOOKIE(a) (((a)->flags & FCTX_ADDRINFO_BADCOOKIE) != 0)
|
||||||
#define ISDUALSTACK(a) (((a)->flags & FCTX_ADDRINFO_DUALSTACK) != 0)
|
#define ISDUALSTACK(a) (((a)->flags & FCTX_ADDRINFO_DUALSTACK) != 0)
|
||||||
|
|
||||||
#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
|
#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
|
||||||
#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
|
#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
|
||||||
|
#define STATICSTUB(r) (((r)->attributes & DNS_RDATASETATTR_STATICSTUB) != 0)
|
||||||
|
|
||||||
#ifdef ENABLE_AFL
|
#ifdef ENABLE_AFL
|
||||||
bool dns_fuzzing_resolver = false;
|
bool dns_fuzzing_resolver = false;
|
||||||
@@ -3596,6 +3597,7 @@ normal_nses:
|
|||||||
result = dns_rdataset_next(&fctx->nameservers))
|
result = dns_rdataset_next(&fctx->nameservers))
|
||||||
{
|
{
|
||||||
bool overquota = false;
|
bool overquota = false;
|
||||||
|
unsigned int static_stub = 0;
|
||||||
|
|
||||||
dns_rdataset_current(&fctx->nameservers, &rdata);
|
dns_rdataset_current(&fctx->nameservers, &rdata);
|
||||||
/*
|
/*
|
||||||
@@ -3606,13 +3608,19 @@ normal_nses:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (STATICSTUB(&fctx->nameservers) &&
|
||||||
|
dns_name_equal(&ns.name, fctx->domain))
|
||||||
|
{
|
||||||
|
static_stub = DNS_ADBFIND_STATICSTUB;
|
||||||
|
}
|
||||||
|
|
||||||
if (no_addresses > NS_FAIL_LIMIT &&
|
if (no_addresses > NS_FAIL_LIMIT &&
|
||||||
dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT)
|
dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT)
|
||||||
{
|
{
|
||||||
stdoptions |= DNS_ADBFIND_NOFETCH;
|
stdoptions |= DNS_ADBFIND_NOFETCH;
|
||||||
}
|
}
|
||||||
findname(fctx, &ns.name, 0, stdoptions, 0, now, &overquota,
|
findname(fctx, &ns.name, 0, stdoptions | static_stub, 0, now,
|
||||||
&need_alternate, &no_addresses);
|
&overquota, &need_alternate, &no_addresses);
|
||||||
|
|
||||||
if (!overquota) {
|
if (!overquota) {
|
||||||
all_spilled = false;
|
all_spilled = false;
|
||||||
|
@@ -930,7 +930,9 @@ db_find:
|
|||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == ISC_R_NOTFOUND && use_hints && view->hints != NULL) {
|
if (result == ISC_R_NOTFOUND && !is_staticstub_zone && use_hints &&
|
||||||
|
view->hints != NULL)
|
||||||
|
{
|
||||||
if (dns_rdataset_isassociated(rdataset)) {
|
if (dns_rdataset_isassociated(rdataset)) {
|
||||||
dns_rdataset_disassociate(rdataset);
|
dns_rdataset_disassociate(rdataset);
|
||||||
}
|
}
|
||||||
@@ -1145,6 +1147,14 @@ db_find:
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tag static stub NS RRset so that when we look for
|
||||||
|
* addresses we use the configured server addresses.
|
||||||
|
*/
|
||||||
|
if (dns_zone_gettype(zone) == dns_zone_staticstub) {
|
||||||
|
rdataset->attributes |= DNS_RDATASETATTR_STATICSTUB;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_cache && view->cachedb != NULL && db != view->hints) {
|
if (use_cache && view->cachedb != NULL && db != view->hints) {
|
||||||
/*
|
/*
|
||||||
* We found an answer, but the cache may be better.
|
* We found an answer, but the cache may be better.
|
||||||
|
Reference in New Issue
Block a user