}
static void
-copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name) {
+copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name,
+ size_t maxfindlen, size_t *findlen) {
dns_adbentry_t *entry = NULL;
+ size_t count = 0;
if ((find->options & DNS_ADBFIND_INET) != 0) {
ISC_LIST_FOREACH(name->v4, namehook, name_link) {
* Found a valid entry. Add it to the find's list.
*/
ISC_LIST_APPEND(find->list, addrinfo, publink);
+
+ count++;
+ if (maxfindlen - count == 0) {
+ SET_IF_NOT_NULL(findlen, count);
+ return;
+ }
}
}
* Found a valid entry. Add it to the find's list.
*/
ISC_LIST_APPEND(find->list, addrinfo, publink);
+
+ count++;
+ if (maxfindlen - count == 0) {
+ SET_IF_NOT_NULL(findlen, count);
+ return;
+ }
}
}
+
+ SET_IF_NOT_NULL(findlen, count);
}
static bool
void
dns_adb_createaddrinfosfind(dns_adb_t *adb, isc_netaddrlist_t *addrs,
in_port_t port, unsigned int options,
- isc_stdtime_t now, size_t maxaddrs,
+ isc_stdtime_t now, size_t maxfindlen,
dns_adbfind_t **findp, size_t *findlen) {
dns_adbfind_t *find = NULL;
isc_sockaddr_t sockaddr = {};
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(addrs != NULL);
REQUIRE(findp != NULL && *findp == NULL);
- REQUIRE(maxaddrs > 0);
+ REQUIRE(maxfindlen > 0);
rcu_read_lock();
ISC_LIST_APPEND(find->list, addrinfo, publink);
(*findlen)++;
- if (maxaddrs - *findlen == 0) {
+ if (maxfindlen - *findlen == 0) {
break;
}
}
const dns_name_t *name, unsigned int options,
isc_stdtime_t now, in_port_t port, unsigned int depth,
isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
- dns_adbfind_t **findp) {
+ size_t maxfindlen, dns_adbfind_t **findp, size_t *findlen) {
isc_result_t result = ISC_R_UNEXPECTED;
dns_adbfind_t *find = NULL;
dns_adbname_t *adbname = NULL;
}
REQUIRE(name != NULL);
REQUIRE(findp != NULL && *findp == NULL);
+ REQUIRE(maxfindlen > 0);
REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0);
* Run through the name and copy out the bits we are
* interested in.
*/
- copy_namehook_lists(adb, find, adbname);
+ copy_namehook_lists(adb, find, adbname, maxfindlen, findlen);
post_copy:
if (NAME_FETCH_A(adbname)) {
const dns_name_t *name, unsigned int options,
isc_stdtime_t now, in_port_t port, unsigned int depth,
isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
- dns_adbfind_t **find);
+ size_t maxfindlen, dns_adbfind_t **find, size_t *findlen);
/*%<
* Main interface for clients. The adb will look up the name given in
* "name" and will build up a list of found addresses, and perhaps start
*
*\li find != NULL && *find == NULL.
*
+ *\li findlen is optional, if not NULL, it will be set to the length of find.
+ *
* Returns:
*
*\li #ISC_R_SUCCESS Addresses might have been returned, and events will be
goto destroy;
}
- result = dns_adb_createfind(adb, loop, process_notify_adb_event, notify,
- ¬ify->ns, options, 0, notify->port, 0,
- NULL, NULL, NULL, ¬ify->find);
+ result = dns_adb_createfind(
+ adb, loop, process_notify_adb_event, notify, ¬ify->ns,
+ options, 0, notify->port, 0, NULL, NULL, NULL,
+ view->max_delegation_servers, ¬ify->find, NULL);
dns_adb_detach(&adb);
/* Something failed? */
static void
findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
unsigned int options, unsigned int flags, isc_stdtime_t now,
- bool *overquota, bool *need_alternate, bool *have_address) {
+ bool *overquota, bool *need_alternate, bool *have_address,
+ size_t maxfindlen, size_t *findlen) {
dns_adbfind_t *find = NULL;
dns_resolver_t *res = fctx->res;
bool unshared = ((fctx->options & DNS_FETCHOPT_UNSHARED) != 0);
result = dns_adb_createfind(fctx->adb, fctx->loop, fctx_finddone, fctx,
name, options, now, res->view->dstport,
fctx->depth + 1, fctx->qc, fctx->gqc, fctx,
- &find);
+ maxfindlen, &find, findlen);
isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
ISC_LOG_DEBUG(3), "fctx %p(%s): createfind for %s - %s",
ISC_LIST_FOREACH(fctx->delegset->delegs, deleg, link) {
dns_adbfind_t *find = NULL;
- size_t maxaddrs = max_delegation_servers - *ns_processed;
+ size_t maxfindlen = max_delegation_servers - *ns_processed;
size_t findlen = 0;
if (*ns_processed >= max_delegation_servers) {
fetchctx_ref(fctx);
dns_adb_createaddrinfosfind(fctx->adb, &deleg->addresses,
fctx->res->view->dstport, options,
- now, maxaddrs, &find, &findlen);
+ now, maxfindlen, &find, &findlen);
if (find == NULL) {
fetchctx_unref(fctx);
unsigned int static_stub = 0;
unsigned int no_fetch = 0;
dns_name_t *ns = nameservers[i];
+ size_t maxfindlen = max_delegation_servers - *ns_processed;
+ size_t findlen = 0;
+
+ if (*ns_processed >= max_delegation_servers) {
+ break;
+ }
if (fctx->delegset->staticstub &&
dns_name_equal(ns, fctx->domain))
}
findname(fctx, ns, 0, stdoptions | static_stub | no_fetch, 0,
- now, &overquota, need_alternatep, &have_address);
+ now, &overquota, need_alternatep, &have_address,
+ maxfindlen, &findlen);
if (!overquota) {
*all_spilledp = false;
}
+ *ns_processed += findlen;
- if (++(*ns_processed) >= max_delegation_servers) {
- break;
- }
+ INSIST(*ns_processed <= max_delegation_servers);
}
if (fctx->pending_running == 0 && !have_address) {
if (!a->isaddress) {
findname(fctx, &a->_u._n.name, a->_u._n.port,
stdoptions, FCTX_ADDRINFO_DUALSTACK, now, NULL,
- NULL, NULL);
+ NULL, NULL,
+ fctx->res->view->max_delegation_servers, NULL);
continue;
}
if (isc_sockaddr_pf(&a->_u.addr) != family) {
isc_result_t result;
unsigned int options;
dns_adb_t *adb = NULL;
+ dns_view_t *view = NULL;
REQUIRE(DNS_CHECKDS_VALID(checkds));
+ view = checkds->zone->view;
options = DNS_ADBFIND_WANTEVENT;
if (isc_net_probeipv4() != ISC_R_DISABLED) {
options |= DNS_ADBFIND_INET;
options |= DNS_ADBFIND_INET6;
}
- dns_view_getadb(checkds->zone->view, &adb);
+ dns_view_getadb(view, &adb);
if (adb == NULL) {
goto destroy;
}
result = dns_adb_createfind(
adb, checkds->zone->loop, process_checkds_adb_event, checkds,
&checkds->ns, options, 0, checkds->zone->view->dstport, 0, NULL,
- NULL, NULL, &checkds->find);
+ NULL, NULL, view->max_delegation_servers, &checkds->find, NULL);
dns_adb_detach(&adb);
/* Something failed? */