Commit 05e44893 authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] refactor max-recursion-queries

- the counters weren't set correctly when fetches timed out.
  instead we now pass down a counter object.
parent 795beed7
......@@ -3908,7 +3908,7 @@ query_prefetch(ns_client_t *client, dns_name_t *qname,
result = dns_resolver_createfetch3(client->view->resolver,
qname, rdataset->type, NULL, NULL,
NULL, peeraddr, client->message->id,
options, 0, client->task,
options, 0, NULL, client->task,
prefetch_done, client,
tmprdataset, NULL,
&client->query.prefetch);
......@@ -4029,7 +4029,7 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
result = dns_resolver_createfetch3(client->view->resolver,
qname, qtype, qdomain, nameservers,
NULL, peeraddr, client->message->id,
client->query.fetchoptions, 0,
client->query.fetchoptions, 0, NULL,
client->task, query_resume, client,
rdataset, sigrdataset,
&client->query.fetch);
......
......@@ -5,5 +5,7 @@ system test for recursion limits
ns1 -- root server
ans2 -- delegate to ns1.(n+1).example.com for all n, up to
the value specified in ans.limit
the value specified in ans.limit (or forever if limit is 0)
ns3 -- resolver under test
ans4 -- delegates every query to 16 more name servers, with "victim" address
ans7 -- "victim" server
......@@ -34,13 +34,13 @@ my $send_response = 0;
sub getlimit {
if ( -e "ans.limit") {
open(FH, "<", "ans.limit");
my $line = <FH>;
chomp $line;
close FH;
if ($line =~ /^\d+$/) {
return $line;
}
open(FH, "<", "ans.limit");
my $line = <FH>;
chomp $line;
close FH;
if ($line =~ /^\d+$/) {
return $line;
}
}
return 0;
......@@ -61,53 +61,53 @@ sub reply_handler {
$count += 1;
if ($qname eq "count" ) {
if ($qtype eq "TXT") {
my ($ttl, $rdata) = (0, "$count");
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
print ("\tcount: $count\n");
}
$rcode = "NOERROR";
if ($qtype eq "TXT") {
my ($ttl, $rdata) = (0, "$count");
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
print ("\tcount: $count\n");
}
$rcode = "NOERROR";
} elsif ($qname eq "reset" ) {
$count = 0;
$send_response = 0;
$limit = getlimit();
$rcode = "NOERROR";
print ("\tlimit: $limit\n");
$count = 0;
$send_response = 0;
$limit = getlimit();
$rcode = "NOERROR";
print ("\tlimit: $limit\n");
} elsif ($qname eq "direct.example.org" ) {
if ($qtype eq "A") {
my ($ttl, $rdata) = (3600, $localaddr);
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
}
$rcode = "NOERROR";
if ($qtype eq "A") {
my ($ttl, $rdata) = (3600, $localaddr);
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
}
$rcode = "NOERROR";
} elsif ($qname eq "indirect.example.org") {
if (! $send_response) {
my $rr = new Net::DNS::RR("indirect.example.org 86400 $qclass NS ns1.1.example.org");
push @auth, $rr;
} elsif ($qtype eq "A") {
my ($ttl, $rdata) = (3600, $localaddr);
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
}
$rcode = "NOERROR";
if (! $send_response) {
my $rr = new Net::DNS::RR("indirect.example.org 86400 $qclass NS ns1.1.example.org");
push @auth, $rr;
} elsif ($qtype eq "A") {
my ($ttl, $rdata) = (3600, $localaddr);
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
}
$rcode = "NOERROR";
} elsif ($qname =~ /^ns1\.(\d+)\.example\.org$/) {
my $next = $1 + 1;
if ($limit == 0 || (! $send_response && $next <= $limit)) {
my $rr = new Net::DNS::RR("$1.example.org 86400 $qclass NS ns1.$next.example.org");
push @auth, $rr;
} else {
$send_response = 1;
if ($qtype eq "A") {
my ($ttl, $rdata) = (3600, $localaddr);
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
print("\tresponse: $qname $ttl $qclass $qtype $rdata\n");
push @ans, $rr;
}
}
$rcode = "NOERROR";
my $next = $1 + 1;
if ($limit == 0 || (! $send_response && $next <= $limit)) {
my $rr = new Net::DNS::RR("$1.example.org 86400 $qclass NS ns1.$next.example.org");
push @auth, $rr;
} else {
$send_response = 1;
if ($qtype eq "A") {
my ($ttl, $rdata) = (3600, $localaddr);
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
print("\tresponse: $qname $ttl $qclass $qtype $rdata\n");
push @ans, $rr;
}
}
$rcode = "NOERROR";
} else {
$rcode = "NXDOMAIN";
$rcode = "NXDOMAIN";
}
# mark the answer as authoritive (by setting the 'aa' flag
......
#!/usr/bin/env perl
use strict;
use warnings;
use IO::File;
use Getopt::Long;
use Net::DNS::Nameserver;
my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
print $pidf "$$\n" or die "cannot write pid file: $!";
$pidf->close or die "cannot close pid file: $!";
sub rmpid { unlink "ans.pid"; exit 1; };
$SIG{INT} = \&rmpid;
$SIG{TERM} = \&rmpid;
my $count = 0;
my $send_response = 0;
my $localaddr = "10.53.0.4";
my $localport = 5300;
my $verbose = 0;
sub reply_handler {
my ($qname, $qclass, $qtype, $peerhost, $query, $conn) = @_;
my ($rcode, @ans, @auth, @add);
print ("request: $qname/$qtype\n");
STDOUT->flush();
$count += 1;
if ($qname eq "count" ) {
if ($qtype eq "TXT") {
my ($ttl, $rdata) = (0, "$count");
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
print ("\tcount: $count\n");
}
$rcode = "NOERROR";
} elsif ($qname eq "reset" ) {
$count = 0;
$send_response = 0;
$rcode = "NOERROR";
} elsif ($qname eq "direct.example.net" ) {
if ($qtype eq "A") {
my ($ttl, $rdata) = (3600, $localaddr);
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
}
$rcode = "NOERROR";
} elsif( $qname =~ /^ns1\.(\d+)\.example\.net$/ ) {
my $next = ($1 + 1) * 16;
for (my $i = 1; $i < 16; $i++) {
my $s = $next + $i;
my $rr = new Net::DNS::RR("$1.example.net 86400 $qclass NS ns1.$s.example.net");
push @auth, $rr;
$rr = new Net::DNS::RR("ns1.$s.example.net 86400 $qclass A 10.53.0.7");
push @add, $rr;
}
$rcode = "NOERROR";
} else {
$rcode = "NXDOMAIN";
}
# mark the answer as authoritive (by setting the 'aa' flag
return ($rcode, \@ans, \@auth, \@add, { aa => 1 });
}
GetOptions(
'port=i' => \$localport,
'verbose!' => \$verbose,
);
my $ns = Net::DNS::Nameserver->new(
LocalAddr => $localaddr,
LocalPort => $localport,
ReplyHandler => \&reply_handler,
Verbose => $verbose,
);
$ns->main_loop;
#!/usr/bin/env perl
use strict;
use warnings;
use IO::File;
use Getopt::Long;
use Net::DNS::Nameserver;
my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
print $pidf "$$\n" or die "cannot write pid file: $!";
$pidf->close or die "cannot close pid file: $!";
sub rmpid { unlink "ans.pid"; exit 1; };
$SIG{INT} = \&rmpid;
$SIG{TERM} = \&rmpid;
my $count = 0;
my $localaddr = "10.53.0.7";
my $localport = 5300;
my $verbose = 0;
sub reply_handler {
my ($qname, $qclass, $qtype, $peerhost, $query, $conn) = @_;
my ($rcode, @ans, @auth, @add);
print ("request: $qname/$qtype\n");
STDOUT->flush();
$count += 1;
if ($qname eq "count" ) {
if ($qtype eq "TXT") {
my ($ttl, $rdata) = (0, "$count");
my $rr = new Net::DNS::RR("$qname $ttl $qclass $qtype $rdata");
push @ans, $rr;
print ("\tcount: $count\n");
}
$rcode = "NOERROR";
} elsif ($qname eq "reset") {
$count = 0;
$rcode = "NOERROR";
} else {
$rcode = "REFUSED";
}
# mark the answer as authoritive (by setting the 'aa' flag
return ($rcode, \@ans, \@auth, \@add, { aa => 1 });
}
GetOptions(
'port=i' => \$localport,
'verbose!' => \$verbose,
);
my $ns = Net::DNS::Nameserver->new(
LocalAddr => $localaddr,
LocalPort => $localport,
ReplyHandler => \&reply_handler,
Verbose => $verbose,
);
$ns->main_loop;
......@@ -18,3 +18,5 @@ ns.nil. 60 IN A 10.53.0.1
ns.tld1. 60 IN A 10.53.0.1
example.org. 60 IN NS direct.example.org.
direct.example.org. 60 IN A 10.53.0.2
example.net. 60 IN NS direct.example.net.
direct.example.net. 60 IN A 10.53.0.4
......@@ -90,29 +90,28 @@ sleep 2
n=`expr $n + 1`
echo "I: attempt excessive-queries lookup ($n)"
ret=0
echo "25" > ans2/ans.limit
echo "13" > ans2/ans.limit
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
grep "exceeded max queries resolving 'indirect.example.org/A'" ns3/named.run > /dev/null || ret=1
$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -eq 100 ] || ret=1
[ $count -le 50 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: attempt permissible lookup ($n)"
ret=0
echo "24" > ans2/ans.limit
echo "12" > ans2/ans.limit
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -eq 97 ] || ret=1
[ $count -le 50 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
......@@ -124,29 +123,43 @@ sleep 2
n=`expr $n + 1`
echo "I: attempt excessive-queries lookup ($n)"
ret=0
echo "21" > ans2/ans.limit
echo "10" > ans2/ans.limit
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
grep "exceeded max queries resolving 'indirect.example.org/A'" ns3/named.run > /dev/null || ret=1
$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -eq 84 ] || ret=1
[ $count -le 40 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: attempt permissible lookup ($n)"
ret=0
echo "19" > ans2/ans.limit
echo "9" > ans2/ans.limit
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
$DIG $DIGOPTS @10.53.0.3 indirect.example.org > dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -eq 77 ] || ret=1
[ $count -le 40 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo "I: attempting NS explosion ($n)"
ret=0
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush 2>&1 | sed 's/^/I:ns1 /'
$DIG $DIGOPTS +short @10.53.0.3 ns1.1.example.net > dig.out.1.test$n || ret=1
sleep 2
$DIG $DIGOPTS +short @10.53.0.4 count txt > dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -lt 50 ] || ret=1
$DIG $DIGOPTS +short @10.53.0.7 count txt > dig.out.3.test$n || ret=1
eval count=`cat dig.out.3.test$n`
[ $count -lt 50 ] || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
......
......@@ -313,8 +313,7 @@ static inline isc_boolean_t dec_entry_refcnt(dns_adb_t *, isc_boolean_t,
static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
static isc_boolean_t clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
static void clean_target(dns_adb_t *, dns_name_t *);
static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
isc_uint32_t, unsigned int);
static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, unsigned int);
static isc_boolean_t check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
static isc_boolean_t check_expire_entry(dns_adb_t *, dns_adbentry_t **,
isc_stdtime_t);
......@@ -322,7 +321,8 @@ static void cancel_fetches_at_name(dns_adbname_t *);
static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
dns_rdatatype_t);
static isc_result_t fetch_name(dns_adbname_t *, isc_boolean_t,
unsigned int, dns_rdatatype_t);
unsigned int, isc_counter_t *qc,
dns_rdatatype_t);
static inline void check_exit(dns_adb_t *);
static void destroy(dns_adb_t *);
static isc_boolean_t shutdown_names(dns_adb_t *);
......@@ -1025,7 +1025,7 @@ kill_name(dns_adbname_t **n, isc_eventtype_t ev) {
* Clean up the name's various lists. These two are destructive
* in that they will always empty the list.
*/
clean_finds_at_name(name, ev, 0, DNS_ADBFIND_ADDRESSMASK);
clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
result4 = clean_namehooks(adb, &name->v4);
result6 = clean_namehooks(adb, &name->v6);
clean_target(adb, &name->target);
......@@ -1450,7 +1450,7 @@ event_free(isc_event_t *event) {
*/
static void
clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
isc_uint32_t qtotal, unsigned int addrs)
unsigned int addrs)
{
isc_event_t *ev;
isc_task_t *task;
......@@ -1510,7 +1510,6 @@ clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
ev->ev_sender = find;
find->result_v4 = find_err_map[name->fetch_err];
find->result_v6 = find_err_map[name->fetch6_err];
find->qtotal += qtotal;
ev->ev_type = evtype;
ev->ev_destroy = event_free;
ev->ev_destroy_arg = find;
......@@ -1886,7 +1885,6 @@ new_adbfind(dns_adb_t *adb) {
h->flags = 0;
h->result_v4 = ISC_R_UNEXPECTED;
h->result_v6 = ISC_R_UNEXPECTED;
h->qtotal = 0;
ISC_LINK_INIT(h, publink);
ISC_LINK_INIT(h, plink);
ISC_LIST_INIT(h->list);
......@@ -2870,7 +2868,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
{
return (dns_adb_createfind2(adb, task, action, arg, name,
qname, qtype, options, now,
target, port, 0, findp));
target, port, 0, NULL, findp));
}
isc_result_t
......@@ -2878,7 +2876,7 @@ dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
void *arg, dns_name_t *name, dns_name_t *qname,
dns_rdatatype_t qtype, unsigned int options,
isc_stdtime_t now, dns_name_t *target,
in_port_t port, unsigned int depth,
in_port_t port, unsigned int depth, isc_counter_t *qc,
dns_adbfind_t **findp)
{
dns_adbfind_t *find;
......@@ -3117,7 +3115,7 @@ dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* Start V4.
*/
if (WANT_INET(wanted_fetches) &&
fetch_name(adbname, start_at_zone, depth,
fetch_name(adbname, start_at_zone, depth, qc,
dns_rdatatype_a) == ISC_R_SUCCESS) {
DP(DEF_LEVEL, "dns_adb_createfind: "
"started A fetch for name %s (%p)",
......@@ -3128,7 +3126,7 @@ dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* Start V6.
*/
if (WANT_INET6(wanted_fetches) &&
fetch_name(adbname, start_at_zone, depth,
fetch_name(adbname, start_at_zone, depth, qc,
dns_rdatatype_aaaa) == ISC_R_SUCCESS) {
DP(DEF_LEVEL, "dns_adb_createfind: "
"started AAAA fetch for name %s (%p)",
......@@ -3760,7 +3758,6 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) {
isc_result_t result;
unsigned int address_type;
isc_boolean_t want_check_exit = ISC_FALSE;
isc_uint32_t qtotal = 0;
UNUSED(task);
......@@ -3771,8 +3768,6 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) {
adb = name->adb;
INSIST(DNS_ADB_VALID(adb));
qtotal = dev->qtotal;
bucket = name->lock_bucket;
LOCK(&adb->namelocks[bucket]);
......@@ -3927,14 +3922,14 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) {
free_adbfetch(adb, &fetch);
isc_event_free(&ev);
clean_finds_at_name(name, ev_status, qtotal, address_type);
clean_finds_at_name(name, ev_status, address_type);
UNLOCK(&adb->namelocks[bucket]);
}
static isc_result_t
fetch_name(dns_adbname_t *adbname, isc_boolean_t start_at_zone,
unsigned int depth, dns_rdatatype_t type)
unsigned int depth, isc_counter_t *qc, dns_rdatatype_t type)
{
isc_result_t result;
dns_adbfetch_t *fetch = NULL;
......@@ -3983,8 +3978,8 @@ fetch_name(dns_adbname_t *adbname, isc_boolean_t start_at_zone,
result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name,
type, name, nameservers, NULL,
NULL, 0, options, depth, adb->task,
fetch_callback, adbname,
NULL, 0, options, depth, qc,
adb->task, fetch_callback, adbname,
&fetch->rdataset, NULL,
&fetch->fetch);
if (result != ISC_R_SUCCESS)
......
......@@ -118,8 +118,6 @@ struct dns_adbfind {
isc_result_t result_v6; /*%< RO: v6 result */
ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */
isc_uint32_t qtotal;
/* Private */
isc_mutex_t lock; /* locks all below */
in_port_t port;
......@@ -343,7 +341,8 @@ dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
void *arg, dns_name_t *name, dns_name_t *qname,
dns_rdatatype_t qtype, unsigned int options,
isc_stdtime_t now, dns_name_t *target, in_port_t port,
unsigned int depth, dns_adbfind_t **find);
unsigned int depth, isc_counter_t *qc,
dns_adbfind_t **find);
/*%<
* 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
......
......@@ -82,7 +82,6 @@ typedef struct dns_fetchevent {
isc_sockaddr_t * client;
dns_messageid_t id;
isc_result_t vresult;
isc_uint32_t qtotal;
} dns_fetchevent_t;
/*
......@@ -286,7 +285,7 @@ dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name,
dns_forwarders_t *forwarders,
isc_sockaddr_t *client, isc_uint16_t id,
unsigned int options, unsigned int depth,
isc_task_t *task,
isc_counter_t *qc, isc_task_t *task,
isc_taskaction_t action, void *arg,
dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset,
......
......@@ -20,6 +20,7 @@
#include <config.h>
#include <ctype.h>
#include <isc/counter.h>
#include <isc/log.h>
#include <isc/platform.h>
#include <isc/print.h>
......@@ -281,12 +282,13 @@ struct fetchctx {
ISC_LIST(struct tried) edns;
ISC_LIST(struct tried) edns512;
isc_sockaddrlist_t bad_edns;
dns_validator_t *validator;
dns_validator_t * validator;
ISC_LIST(dns_validator_t) validators;
dns_db_t * cache;
dns_adb_t * adb;
isc_boolean_t ns_ttl_ok;
isc_uint32_t ns_ttl;
isc_counter_t * qc;
/*%
* The number of events we're waiting for.
......@@ -344,7 +346,6 @@ struct fetchctx {
isc_uint64_t duration;
isc_boolean_t logged;
unsigned int querysent;
unsigned int totalqueries;
unsigned int referrals;
unsigned int lamecount;
unsigned int neterr;
......@@ -1176,7 +1177,6 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
event->result == DNS_R_NCACHENXRRSET);
}
event->qtotal = fctx->totalqueries;
isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event));
count++;
}
......@@ -1643,7 +1643,6 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
}
fctx->querysent++;
fctx->totalqueries++;
ISC_LIST_APPEND(fctx->queries, query, link);
query->fctx->nqueries++;
......@@ -2540,7 +2539,6 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
*/
INSIST(!SHUTTINGDOWN(fctx));
fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
fctx->totalqueries += find->qtotal;