* Internal functions (and prototypes).
*/
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
destroy_adbname(dns_adbname_t *);
static bool
purge_stale_names(dns_adb_t *adb, isc_stdtime_t now);
static dns_adbname_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
purge_stale_entries(dns_adb_t *adb, isc_stdtime_t now);
static dns_adbentry_t *
#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) != 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_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
* not really associated with any particular type.
}
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;
name = isc_mem_get(adb->mctx, sizeof(*name));
.v6 = ISC_LIST_INITIALIZER,
.finds = ISC_LIST_INITIALIZER,
.link = ISC_LINK_INITIALIZER,
+ .flags = flags & ADBNAME_FLAGS_MASK,
.magic = DNS_ADBNAME_MAGIC,
};
dns_name_copy(dnsname, name->name);
dns_name_init(&name->target, NULL);
- if (start_at_zone) {
- name->flags |= DNS_ADBFIND_STARTATZONE;
- }
-
inc_adbstats(adb, dns_adbstats_namescnt);
return (name);
}
const dns_adbname_t *adbname0 = node;
const dns_adbname_t *adbname1 = key;
- if ((adbname0->flags & DNS_ADBFIND_STARTATZONE) !=
- (adbname1->flags & DNS_ADBFIND_STARTATZONE))
+ if ((adbname0->flags & ADBNAME_FLAGS_MASK) !=
+ (adbname1->flags & ADBNAME_FLAGS_MASK))
{
return (false);
}
static uint32_t
hash_adbname(const dns_adbname_t *adbname) {
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_hash(&hash, adbname->name->ndata, adbname->name->length,
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));
}
*/
static dns_adbname_t *
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;
dns_adbname_t *adbname = NULL;
isc_time_t timenow;
isc_stdtime_t last_update;
dns_adbname_t key = {
.name = UNCONST(name),
- .flags = (start_at_zone) ? DNS_ADBFIND_STARTATZONE : 0,
+ .flags = flags & ADBNAME_FLAGS_MASK,
};
uint32_t hashval = hash_adbname(&key);
isc_rwlocktype_t locktype = isc_rwlocktype_read;
UPGRADELOCK(&adb->names_lock, locktype);
/* 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;
result = isc_hashmap_add(adb->names, hashval, match_adbname,
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.
*/
again:
/* Try to see if we know anything about this name at all. */
- adbname = get_attached_and_locked_name(adb, name,
- FIND_STARTATZONE(find), now);
+ adbname = get_attached_and_locked_name(adb, name, find->options, now);
if (NAME_DEAD(adbname)) {
UNLOCK(&adbname->lock);
* Any other result, start a fetch for A, then fall
* through to AAAA.
*/
- if (!NAME_FETCH_A(adbname)) {
+ if (!NAME_FETCH_A(adbname) && !FIND_STATICSTUB(find)) {
wanted_fetches |= DNS_ADBFIND_INET;
}
break;
/*
* 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;
}
break;
dns_adbname_t *adbname = NULL;
isc_result_t result;
bool start_at_zone = false;
+ bool static_stub = false;
dns_adbname_t key = { .name = UNCONST(name) };
REQUIRE(DNS_ADB_VALID(adb));
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
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,
(void *)&key, (void **)&adbname);
start_at_zone = true;
goto again;
}
+ if (!static_stub) {
+ static_stub = true;
+ goto again;
+ }
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
}
#define BADCOOKIE(a) (((a)->flags & FCTX_ADDRINFO_BADCOOKIE) != 0)
#define ISDUALSTACK(a) (((a)->flags & FCTX_ADDRINFO_DUALSTACK) != 0)
-#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
-#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+#define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
+#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+#define STATICSTUB(r) (((r)->attributes & DNS_RDATASETATTR_STATICSTUB) != 0)
#ifdef ENABLE_AFL
bool dns_fuzzing_resolver = false;
result = dns_rdataset_next(&fctx->nameservers))
{
bool overquota = false;
+ unsigned int static_stub = 0;
dns_rdataset_current(&fctx->nameservers, &rdata);
/*
continue;
}
+ if (STATICSTUB(&fctx->nameservers) &&
+ dns_name_equal(&ns.name, fctx->domain))
+ {
+ static_stub = DNS_ADBFIND_STATICSTUB;
+ }
+
if (no_addresses > NS_FAIL_LIMIT &&
dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT)
{
stdoptions |= DNS_ADBFIND_NOFETCH;
}
- findname(fctx, &ns.name, 0, stdoptions, 0, now, &overquota,
- &need_alternate, &no_addresses);
+ findname(fctx, &ns.name, 0, stdoptions | static_stub, 0, now,
+ &overquota, &need_alternate, &no_addresses);
if (!overquota) {
all_spilled = false;