]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - contrib/bind9/lib/dns/resolver.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / contrib / bind9 / lib / dns / resolver.c
1 /*
2  * Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: resolver.c,v 1.384.14.14 2009/06/02 23:47:13 tbox Exp $ */
19
20 /*! \file */
21
22 #include <config.h>
23
24 #include <isc/platform.h>
25 #include <isc/print.h>
26 #include <isc/string.h>
27 #include <isc/random.h>
28 #include <isc/task.h>
29 #include <isc/stats.h>
30 #include <isc/timer.h>
31 #include <isc/util.h>
32
33 #include <dns/acl.h>
34 #include <dns/adb.h>
35 #include <dns/cache.h>
36 #include <dns/db.h>
37 #include <dns/dispatch.h>
38 #include <dns/ds.h>
39 #include <dns/events.h>
40 #include <dns/forward.h>
41 #include <dns/keytable.h>
42 #include <dns/log.h>
43 #include <dns/message.h>
44 #include <dns/ncache.h>
45 #include <dns/opcode.h>
46 #include <dns/peer.h>
47 #include <dns/rbt.h>
48 #include <dns/rcode.h>
49 #include <dns/rdata.h>
50 #include <dns/rdataclass.h>
51 #include <dns/rdatalist.h>
52 #include <dns/rdataset.h>
53 #include <dns/rdatastruct.h>
54 #include <dns/rdatatype.h>
55 #include <dns/resolver.h>
56 #include <dns/result.h>
57 #include <dns/rootns.h>
58 #include <dns/stats.h>
59 #include <dns/tsig.h>
60 #include <dns/validator.h>
61
62 #define DNS_RESOLVER_TRACE
63 #ifdef DNS_RESOLVER_TRACE
64 #define RTRACE(m)       isc_log_write(dns_lctx, \
65                                       DNS_LOGCATEGORY_RESOLVER, \
66                                       DNS_LOGMODULE_RESOLVER, \
67                                       ISC_LOG_DEBUG(3), \
68                                       "res %p: %s", res, (m))
69 #define RRTRACE(r, m)   isc_log_write(dns_lctx, \
70                                       DNS_LOGCATEGORY_RESOLVER, \
71                                       DNS_LOGMODULE_RESOLVER, \
72                                       ISC_LOG_DEBUG(3), \
73                                       "res %p: %s", (r), (m))
74 #define FCTXTRACE(m)    isc_log_write(dns_lctx, \
75                                       DNS_LOGCATEGORY_RESOLVER, \
76                                       DNS_LOGMODULE_RESOLVER, \
77                                       ISC_LOG_DEBUG(3), \
78                                       "fctx %p(%s'): %s", fctx, fctx->info, (m))
79 #define FCTXTRACE2(m1, m2) \
80                         isc_log_write(dns_lctx, \
81                                       DNS_LOGCATEGORY_RESOLVER, \
82                                       DNS_LOGMODULE_RESOLVER, \
83                                       ISC_LOG_DEBUG(3), \
84                                       "fctx %p(%s): %s %s", \
85                                       fctx, fctx->info, (m1), (m2))
86 #define FTRACE(m)       isc_log_write(dns_lctx, \
87                                       DNS_LOGCATEGORY_RESOLVER, \
88                                       DNS_LOGMODULE_RESOLVER, \
89                                       ISC_LOG_DEBUG(3), \
90                                       "fetch %p (fctx %p(%s)): %s", \
91                                       fetch, fetch->private, \
92                                       fetch->private->info, (m))
93 #define QTRACE(m)       isc_log_write(dns_lctx, \
94                                       DNS_LOGCATEGORY_RESOLVER, \
95                                       DNS_LOGMODULE_RESOLVER, \
96                                       ISC_LOG_DEBUG(3), \
97                                       "resquery %p (fctx %p(%s)): %s", \
98                                       query, query->fctx, \
99                                       query->fctx->info, (m))
100 #else
101 #define RTRACE(m)
102 #define RRTRACE(r, m)
103 #define FCTXTRACE(m)
104 #define FTRACE(m)
105 #define QTRACE(m)
106 #endif
107
108 /*%
109  * Maximum EDNS0 input packet size.
110  */
111 #define RECV_BUFFER_SIZE                4096            /* XXXRTH  Constant. */
112
113 /*%
114  * This defines the maximum number of timeouts we will permit before we
115  * disable EDNS0 on the query.
116  */
117 #define MAX_EDNS0_TIMEOUTS      3
118
119 typedef struct fetchctx fetchctx_t;
120
121 typedef struct query {
122         /* Locked by task event serialization. */
123         unsigned int                    magic;
124         fetchctx_t *                    fctx;
125         isc_mem_t *                     mctx;
126         dns_dispatchmgr_t *             dispatchmgr;
127         dns_dispatch_t *                dispatch;
128         isc_boolean_t                   exclusivesocket;
129         dns_adbaddrinfo_t *             addrinfo;
130         isc_socket_t *                  tcpsocket;
131         isc_time_t                      start;
132         dns_messageid_t                 id;
133         dns_dispentry_t *               dispentry;
134         ISC_LINK(struct query)          link;
135         isc_buffer_t                    buffer;
136         isc_buffer_t                    *tsig;
137         dns_tsigkey_t                   *tsigkey;
138         unsigned int                    options;
139         unsigned int                    attributes;
140         unsigned int                    sends;
141         unsigned int                    connects;
142         unsigned char                   data[512];
143 } resquery_t;
144
145 #define QUERY_MAGIC                     ISC_MAGIC('Q', '!', '!', '!')
146 #define VALID_QUERY(query)              ISC_MAGIC_VALID(query, QUERY_MAGIC)
147
148 #define RESQUERY_ATTR_CANCELED          0x02
149
150 #define RESQUERY_CONNECTING(q)          ((q)->connects > 0)
151 #define RESQUERY_CANCELED(q)            (((q)->attributes & \
152                                           RESQUERY_ATTR_CANCELED) != 0)
153 #define RESQUERY_SENDING(q)             ((q)->sends > 0)
154
155 typedef enum {
156         fetchstate_init = 0,            /*%< Start event has not run yet. */
157         fetchstate_active,
158         fetchstate_done                 /*%< FETCHDONE events posted. */
159 } fetchstate;
160
161 typedef enum {
162         badns_unreachable = 0,
163         badns_response,
164         badns_validation
165 } badnstype_t;
166
167 struct fetchctx {
168         /*% Not locked. */
169         unsigned int                    magic;
170         dns_resolver_t *                res;
171         dns_name_t                      name;
172         dns_rdatatype_t                 type;
173         unsigned int                    options;
174         unsigned int                    bucketnum;
175         char *                  info;
176         /*% Locked by appropriate bucket lock. */
177         fetchstate                      state;
178         isc_boolean_t                   want_shutdown;
179         isc_boolean_t                   cloned;
180         isc_boolean_t                   spilled;
181         unsigned int                    references;
182         isc_event_t                     control_event;
183         ISC_LINK(struct fetchctx)       link;
184         ISC_LIST(dns_fetchevent_t)      events;
185         /*% Locked by task event serialization. */
186         dns_name_t                      domain;
187         dns_rdataset_t                  nameservers;
188         unsigned int                    attributes;
189         isc_timer_t *                   timer;
190         isc_time_t                      expires;
191         isc_interval_t                  interval;
192         dns_message_t *                 qmessage;
193         dns_message_t *                 rmessage;
194         ISC_LIST(resquery_t)            queries;
195         dns_adbfindlist_t               finds;
196         dns_adbfind_t *                 find;
197         dns_adbfindlist_t               altfinds;
198         dns_adbfind_t *                 altfind;
199         dns_adbaddrinfolist_t           forwaddrs;
200         dns_adbaddrinfolist_t           altaddrs;
201         isc_sockaddrlist_t              forwarders;
202         dns_fwdpolicy_t                 fwdpolicy;
203         isc_sockaddrlist_t              bad;
204         isc_sockaddrlist_t              edns;
205         isc_sockaddrlist_t              edns512;
206         dns_validator_t                 *validator;
207         ISC_LIST(dns_validator_t)       validators;
208         dns_db_t *                      cache;
209         dns_adb_t *                     adb;
210
211         /*%
212          * The number of events we're waiting for.
213          */
214         unsigned int                    pending;
215
216         /*%
217          * The number of times we've "restarted" the current
218          * nameserver set.  This acts as a failsafe to prevent
219          * us from pounding constantly on a particular set of
220          * servers that, for whatever reason, are not giving
221          * us useful responses, but are responding in such a
222          * way that they are not marked "bad".
223          */
224         unsigned int                    restarts;
225
226         /*%
227          * The number of timeouts that have occurred since we
228          * last successfully received a response packet.  This
229          * is used for EDNS0 black hole detection.
230          */
231         unsigned int                    timeouts;
232
233         /*%
234          * Look aside state for DS lookups.
235          */
236         dns_name_t                      nsname;
237         dns_fetch_t *                   nsfetch;
238         dns_rdataset_t                  nsrrset;
239
240         /*%
241          * Number of queries that reference this context.
242          */
243         unsigned int                    nqueries;
244
245         /*%
246          * The reason to print when logging a successful
247          * response to a query.
248          */
249         const char *                    reason;
250
251         /*%
252          * Random numbers to use for mixing up server addresses.
253          */
254         isc_uint32_t                    rand_buf;
255         isc_uint32_t                    rand_bits;
256
257         /*%
258          * Fetch-local statistics for detailed logging.
259          */
260         isc_result_t                    result; /*%< fetch result  */
261         isc_result_t                    vresult; /*%< validation result  */
262         int                             exitline;
263         isc_time_t                      start;
264         isc_uint64_t                    duration;
265         isc_boolean_t                   logged;
266         unsigned int                    querysent;
267         unsigned int                    referrals;
268         unsigned int                    lamecount;
269         unsigned int                    neterr;
270         unsigned int                    badresp;
271         unsigned int                    adberr;
272         unsigned int                    findfail;
273         unsigned int                    valfail;
274         isc_boolean_t                   timeout;
275 };
276
277 #define FCTX_MAGIC                      ISC_MAGIC('F', '!', '!', '!')
278 #define VALID_FCTX(fctx)                ISC_MAGIC_VALID(fctx, FCTX_MAGIC)
279
280 #define FCTX_ATTR_HAVEANSWER            0x0001
281 #define FCTX_ATTR_GLUING                0x0002
282 #define FCTX_ATTR_ADDRWAIT              0x0004
283 #define FCTX_ATTR_SHUTTINGDOWN          0x0008
284 #define FCTX_ATTR_WANTCACHE             0x0010
285 #define FCTX_ATTR_WANTNCACHE            0x0020
286 #define FCTX_ATTR_NEEDEDNS0             0x0040
287 #define FCTX_ATTR_TRIEDFIND             0x0080
288 #define FCTX_ATTR_TRIEDALT              0x0100
289
290 #define HAVE_ANSWER(f)          (((f)->attributes & FCTX_ATTR_HAVEANSWER) != \
291                                  0)
292 #define GLUING(f)               (((f)->attributes & FCTX_ATTR_GLUING) != \
293                                  0)
294 #define ADDRWAIT(f)             (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \
295                                  0)
296 #define SHUTTINGDOWN(f)         (((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \
297                                  != 0)
298 #define WANTCACHE(f)            (((f)->attributes & FCTX_ATTR_WANTCACHE) != 0)
299 #define WANTNCACHE(f)           (((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0)
300 #define NEEDEDNS0(f)            (((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0)
301 #define TRIEDFIND(f)            (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0)
302 #define TRIEDALT(f)             (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0)
303
304 typedef struct {
305         dns_adbaddrinfo_t *             addrinfo;
306         fetchctx_t *                    fctx;
307 } dns_valarg_t;
308
309 struct dns_fetch {
310         unsigned int                    magic;
311         fetchctx_t *                    private;
312 };
313
314 #define DNS_FETCH_MAGIC                 ISC_MAGIC('F', 't', 'c', 'h')
315 #define DNS_FETCH_VALID(fetch)          ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC)
316
317 typedef struct fctxbucket {
318         isc_task_t *                    task;
319         isc_mutex_t                     lock;
320         ISC_LIST(fetchctx_t)            fctxs;
321         isc_boolean_t                   exiting;
322         isc_mem_t *                     mctx;
323 } fctxbucket_t;
324
325 typedef struct alternate {
326         isc_boolean_t                   isaddress;
327         union   {
328                 isc_sockaddr_t          addr;
329                 struct {
330                         dns_name_t      name;
331                         in_port_t       port;
332                 } _n;
333         } _u;
334         ISC_LINK(struct alternate)      link;
335 } alternate_t;
336
337 struct dns_resolver {
338         /* Unlocked. */
339         unsigned int                    magic;
340         isc_mem_t *                     mctx;
341         isc_mutex_t                     lock;
342         isc_mutex_t                     nlock;
343         isc_mutex_t                     primelock;
344         dns_rdataclass_t                rdclass;
345         isc_socketmgr_t *               socketmgr;
346         isc_timermgr_t *                timermgr;
347         isc_taskmgr_t *                 taskmgr;
348         dns_view_t *                    view;
349         isc_boolean_t                   frozen;
350         unsigned int                    options;
351         dns_dispatchmgr_t *             dispatchmgr;
352         dns_dispatch_t *                dispatchv4;
353         isc_boolean_t                   exclusivev4;
354         dns_dispatch_t *                dispatchv6;
355         isc_boolean_t                   exclusivev6;
356         unsigned int                    ndisps;
357         unsigned int                    nbuckets;
358         fctxbucket_t *                  buckets;
359         isc_uint32_t                    lame_ttl;
360         ISC_LIST(alternate_t)           alternates;
361         isc_uint16_t                    udpsize;
362 #if USE_ALGLOCK
363         isc_rwlock_t                    alglock;
364 #endif
365         dns_rbt_t *                     algorithms;
366 #if USE_MBSLOCK
367         isc_rwlock_t                    mbslock;
368 #endif
369         dns_rbt_t *                     mustbesecure;
370         unsigned int                    spillatmax;
371         unsigned int                    spillatmin;
372         isc_timer_t *                   spillattimer;
373         isc_boolean_t                   zero_no_soa_ttl;
374
375         /* Locked by lock. */
376         unsigned int                    references;
377         isc_boolean_t                   exiting;
378         isc_eventlist_t                 whenshutdown;
379         unsigned int                    activebuckets;
380         isc_boolean_t                   priming;
381         unsigned int                    spillat;        /* clients-per-query */
382         unsigned int                    nextdisp;
383         /* Locked by primelock. */
384         dns_fetch_t *                   primefetch;
385         /* Locked by nlock. */
386         unsigned int                    nfctx;
387 };
388
389 #define RES_MAGIC                       ISC_MAGIC('R', 'e', 's', '!')
390 #define VALID_RESOLVER(res)             ISC_MAGIC_VALID(res, RES_MAGIC)
391
392 /*%
393  * Private addrinfo flags.  These must not conflict with DNS_FETCHOPT_NOEDNS0,
394  * which we also use as an addrinfo flag.
395  */
396 #define FCTX_ADDRINFO_MARK              0x0001
397 #define FCTX_ADDRINFO_FORWARDER         0x1000
398 #define FCTX_ADDRINFO_TRIED             0x2000
399 #define UNMARKED(a)                     (((a)->flags & FCTX_ADDRINFO_MARK) \
400                                          == 0)
401 #define ISFORWARDER(a)                  (((a)->flags & \
402                                          FCTX_ADDRINFO_FORWARDER) != 0)
403 #define TRIED(a)                        (((a)->flags & \
404                                          FCTX_ADDRINFO_TRIED) != 0)
405
406 #define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
407
408 static void destroy(dns_resolver_t *res);
409 static void empty_bucket(dns_resolver_t *res);
410 static isc_result_t resquery_send(resquery_t *query);
411 static void resquery_response(isc_task_t *task, isc_event_t *event);
412 static void resquery_connected(isc_task_t *task, isc_event_t *event);
413 static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying);
414 static isc_boolean_t fctx_destroy(fetchctx_t *fctx);
415 static isc_result_t ncache_adderesult(dns_message_t *message,
416                                       dns_db_t *cache, dns_dbnode_t *node,
417                                       dns_rdatatype_t covers,
418                                       isc_stdtime_t now, dns_ttl_t maxttl,
419                                       isc_boolean_t optout,
420                                       dns_rdataset_t *ardataset,
421                                       isc_result_t *eresultp);
422 static void validated(isc_task_t *task, isc_event_t *event);
423 static void maybe_destroy(fetchctx_t *fctx);
424 static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
425                     isc_result_t reason, badnstype_t badtype);
426
427 /*%
428  * Increment resolver-related statistics counters.
429  */
430 static inline void
431 inc_stats(dns_resolver_t *res, isc_statscounter_t counter) {
432         if (res->view->resstats != NULL)
433                 isc_stats_increment(res->view->resstats, counter);
434 }
435
436 static isc_result_t
437 valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
438           dns_rdatatype_t type, dns_rdataset_t *rdataset,
439           dns_rdataset_t *sigrdataset, unsigned int valoptions,
440           isc_task_t *task)
441 {
442         dns_validator_t *validator = NULL;
443         dns_valarg_t *valarg;
444         isc_result_t result;
445
446         valarg = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
447                              sizeof(*valarg));
448         if (valarg == NULL)
449                 return (ISC_R_NOMEMORY);
450
451         valarg->fctx = fctx;
452         valarg->addrinfo = addrinfo;
453
454         if (!ISC_LIST_EMPTY(fctx->validators))
455                 INSIST((valoptions & DNS_VALIDATOR_DEFER) != 0);
456
457         result = dns_validator_create(fctx->res->view, name, type, rdataset,
458                                       sigrdataset, fctx->rmessage,
459                                       valoptions, task, validated, valarg,
460                                       &validator);
461         if (result == ISC_R_SUCCESS) {
462                 inc_stats(fctx->res, dns_resstatscounter_val);
463                 if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
464                         INSIST(fctx->validator == NULL);
465                         fctx->validator  = validator;
466                 }
467                 ISC_LIST_APPEND(fctx->validators, validator, link);
468         } else
469                 isc_mem_put(fctx->res->buckets[fctx->bucketnum].mctx,
470                             valarg, sizeof(*valarg));
471         return (result);
472 }
473
474 static isc_boolean_t
475 rrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
476         dns_namereln_t namereln;
477         dns_rdata_rrsig_t rrsig;
478         dns_rdata_t rdata = DNS_RDATA_INIT;
479         int order;
480         isc_result_t result;
481         unsigned int labels;
482
483         for (result = dns_rdataset_first(rdataset);
484              result == ISC_R_SUCCESS;
485              result = dns_rdataset_next(rdataset)) {
486                 dns_rdataset_current(rdataset, &rdata);
487                 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
488                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
489                 namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain,
490                                                 &order, &labels);
491                 if (namereln == dns_namereln_subdomain)
492                         return (ISC_TRUE);
493                 dns_rdata_reset(&rdata);
494         }
495         return (ISC_FALSE);
496 }
497
498 static isc_boolean_t
499 fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
500         dns_name_t *name;
501         dns_name_t *domain = &fctx->domain;
502         dns_rdataset_t *rdataset;
503         dns_rdatatype_t type;
504         isc_result_t result;
505         isc_boolean_t keep_auth = ISC_FALSE;
506
507         if (message->rcode == dns_rcode_nxdomain)
508                 return (ISC_FALSE);
509
510         /*
511          * A DS RRset can appear anywhere in a zone, even for a delegation-only
512          * zone.  So a response to an explicit query for this type should be
513          * excluded from delegation-only fixup.
514          *
515          * SOA, NS, and DNSKEY can only exist at a zone apex, so a postive
516          * response to a query for these types can never violate the
517          * delegation-only assumption: if the query name is below a
518          * zone cut, the response should normally be a referral, which should
519          * be accepted; if the query name is below a zone cut but the server
520          * happens to have authority for the zone of the query name, the
521          * response is a (non-referral) answer.  But this does not violate
522          * delegation-only because the query name must be in a different zone
523          * due to the "apex-only" nature of these types.  Note that if the
524          * remote server happens to have authority for a child zone of a
525          * delegation-only zone, we may still incorrectly "fix" the response
526          * with NXDOMAIN for queries for other types.  Unfortunately it's
527          * generally impossible to differentiate this case from violation of
528          * the delegation-only assumption.  Once the resolver learns the
529          * correct zone cut, possibly via a separate query for an "apex-only"
530          * type, queries for other types will be resolved correctly.
531          *
532          * A query for type ANY will be accepted if it hits an exceptional
533          * type above in the answer section as it should be from a child
534          * zone.
535          *
536          * Also accept answers with RRSIG records from the child zone.
537          * Direct queries for RRSIG records should not be answered from
538          * the parent zone.
539          */
540
541         if (message->counts[DNS_SECTION_ANSWER] != 0 &&
542             (fctx->type == dns_rdatatype_ns ||
543              fctx->type == dns_rdatatype_ds ||
544              fctx->type == dns_rdatatype_soa ||
545              fctx->type == dns_rdatatype_any ||
546              fctx->type == dns_rdatatype_rrsig ||
547              fctx->type == dns_rdatatype_dnskey)) {
548                 result = dns_message_firstname(message, DNS_SECTION_ANSWER);
549                 while (result == ISC_R_SUCCESS) {
550                         name = NULL;
551                         dns_message_currentname(message, DNS_SECTION_ANSWER,
552                                                 &name);
553                         for (rdataset = ISC_LIST_HEAD(name->list);
554                              rdataset != NULL;
555                              rdataset = ISC_LIST_NEXT(rdataset, link)) {
556                                 if (!dns_name_equal(name, &fctx->name))
557                                         continue;
558                                 type = rdataset->type;
559                                 /*
560                                  * RRsig from child?
561                                  */
562                                 if (type == dns_rdatatype_rrsig &&
563                                     rrsig_fromchildzone(fctx, rdataset))
564                                         return (ISC_FALSE);
565                                 /*
566                                  * Direct query for apex records or DS.
567                                  */
568                                 if (fctx->type == type &&
569                                     (type == dns_rdatatype_ds ||
570                                      type == dns_rdatatype_ns ||
571                                      type == dns_rdatatype_soa ||
572                                      type == dns_rdatatype_dnskey))
573                                         return (ISC_FALSE);
574                                 /*
575                                  * Indirect query for apex records or DS.
576                                  */
577                                 if (fctx->type == dns_rdatatype_any &&
578                                     (type == dns_rdatatype_ns ||
579                                      type == dns_rdatatype_ds ||
580                                      type == dns_rdatatype_soa ||
581                                      type == dns_rdatatype_dnskey))
582                                         return (ISC_FALSE);
583                         }
584                         result = dns_message_nextname(message,
585                                                       DNS_SECTION_ANSWER);
586                 }
587         }
588
589         /*
590          * A NODATA response to a DS query?
591          */
592         if (fctx->type == dns_rdatatype_ds &&
593             message->counts[DNS_SECTION_ANSWER] == 0)
594                 return (ISC_FALSE);
595
596         /* Look for referral or indication of answer from child zone? */
597         if (message->counts[DNS_SECTION_AUTHORITY] == 0)
598                 goto munge;
599
600         result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
601         while (result == ISC_R_SUCCESS) {
602                 name = NULL;
603                 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
604                 for (rdataset = ISC_LIST_HEAD(name->list);
605                      rdataset != NULL;
606                      rdataset = ISC_LIST_NEXT(rdataset, link)) {
607                         type = rdataset->type;
608                         if (type == dns_rdatatype_soa &&
609                             dns_name_equal(name, domain))
610                                 keep_auth = ISC_TRUE;
611
612                         if (type != dns_rdatatype_ns &&
613                             type != dns_rdatatype_soa &&
614                             type != dns_rdatatype_rrsig)
615                                 continue;
616
617                         if (type == dns_rdatatype_rrsig) {
618                                 if (rrsig_fromchildzone(fctx, rdataset))
619                                         return (ISC_FALSE);
620                                 else
621                                         continue;
622                         }
623
624                         /* NS or SOA records. */
625                         if (dns_name_equal(name, domain)) {
626                                 /*
627                                  * If a query for ANY causes a negative
628                                  * response, we can be sure that this is
629                                  * an empty node.  For other type of queries
630                                  * we cannot differentiate an empty node
631                                  * from a node that just doesn't have that
632                                  * type of record.  We only accept the former
633                                  * case.
634                                  */
635                                 if (message->counts[DNS_SECTION_ANSWER] == 0 &&
636                                     fctx->type == dns_rdatatype_any)
637                                         return (ISC_FALSE);
638                         } else if (dns_name_issubdomain(name, domain)) {
639                                 /* Referral or answer from child zone. */
640                                 return (ISC_FALSE);
641                         }
642                 }
643                 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
644         }
645
646  munge:
647         message->rcode = dns_rcode_nxdomain;
648         message->counts[DNS_SECTION_ANSWER] = 0;
649         if (!keep_auth)
650                 message->counts[DNS_SECTION_AUTHORITY] = 0;
651         message->counts[DNS_SECTION_ADDITIONAL] = 0;
652         return (ISC_TRUE);
653 }
654
655 static inline isc_result_t
656 fctx_starttimer(fetchctx_t *fctx) {
657         /*
658          * Start the lifetime timer for fctx.
659          *
660          * This is also used for stopping the idle timer; in that
661          * case we must purge events already posted to ensure that
662          * no further idle events are delivered.
663          */
664         return (isc_timer_reset(fctx->timer, isc_timertype_once,
665                                 &fctx->expires, NULL, ISC_TRUE));
666 }
667
668 static inline void
669 fctx_stoptimer(fetchctx_t *fctx) {
670         isc_result_t result;
671
672         /*
673          * We don't return a result if resetting the timer to inactive fails
674          * since there's nothing to be done about it.  Resetting to inactive
675          * should never fail anyway, since the code as currently written
676          * cannot fail in that case.
677          */
678         result = isc_timer_reset(fctx->timer, isc_timertype_inactive,
679                                   NULL, NULL, ISC_TRUE);
680         if (result != ISC_R_SUCCESS) {
681                 UNEXPECTED_ERROR(__FILE__, __LINE__,
682                                  "isc_timer_reset(): %s",
683                                  isc_result_totext(result));
684         }
685 }
686
687
688 static inline isc_result_t
689 fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) {
690         /*
691          * Start the idle timer for fctx.  The lifetime timer continues
692          * to be in effect.
693          */
694         return (isc_timer_reset(fctx->timer, isc_timertype_once,
695                                 &fctx->expires, interval, ISC_FALSE));
696 }
697
698 /*
699  * Stopping the idle timer is equivalent to calling fctx_starttimer(), but
700  * we use fctx_stopidletimer for readability in the code below.
701  */
702 #define fctx_stopidletimer      fctx_starttimer
703
704
705 static inline void
706 resquery_destroy(resquery_t **queryp) {
707         resquery_t *query;
708
709         REQUIRE(queryp != NULL);
710         query = *queryp;
711         REQUIRE(!ISC_LINK_LINKED(query, link));
712
713         INSIST(query->tcpsocket == NULL);
714
715         query->fctx->nqueries--;
716         if (SHUTTINGDOWN(query->fctx))
717                 maybe_destroy(query->fctx);     /* Locks bucket. */
718         query->magic = 0;
719         isc_mem_put(query->mctx, query, sizeof(*query));
720         *queryp = NULL;
721 }
722
723 static void
724 fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
725                  isc_time_t *finish, isc_boolean_t no_response)
726 {
727         fetchctx_t *fctx;
728         resquery_t *query;
729         unsigned int rtt, rttms;
730         unsigned int factor;
731         dns_adbfind_t *find;
732         dns_adbaddrinfo_t *addrinfo;
733         isc_socket_t *socket;
734
735         query = *queryp;
736         fctx = query->fctx;
737
738         FCTXTRACE("cancelquery");
739
740         REQUIRE(!RESQUERY_CANCELED(query));
741
742         query->attributes |= RESQUERY_ATTR_CANCELED;
743
744         /*
745          * Should we update the RTT?
746          */
747         if (finish != NULL || no_response) {
748                 if (finish != NULL) {
749                         /*
750                          * We have both the start and finish times for this
751                          * packet, so we can compute a real RTT.
752                          */
753                         rtt = (unsigned int)isc_time_microdiff(finish,
754                                                                &query->start);
755                         factor = DNS_ADB_RTTADJDEFAULT;
756
757                         rttms = rtt / 1000;
758                         if (rttms < DNS_RESOLVER_QRYRTTCLASS0) {
759                                 inc_stats(fctx->res,
760                                           dns_resstatscounter_queryrtt0);
761                         } else if (rttms < DNS_RESOLVER_QRYRTTCLASS1) {
762                                 inc_stats(fctx->res,
763                                           dns_resstatscounter_queryrtt1);
764                         } else if (rttms < DNS_RESOLVER_QRYRTTCLASS2) {
765                                 inc_stats(fctx->res,
766                                           dns_resstatscounter_queryrtt2);
767                         } else if (rttms < DNS_RESOLVER_QRYRTTCLASS3) {
768                                 inc_stats(fctx->res,
769                                           dns_resstatscounter_queryrtt3);
770                         } else if (rttms < DNS_RESOLVER_QRYRTTCLASS4) {
771                                 inc_stats(fctx->res,
772                                           dns_resstatscounter_queryrtt4);
773                         } else {
774                                 inc_stats(fctx->res,
775                                           dns_resstatscounter_queryrtt5);
776                         }
777                 } else {
778                         /*
779                          * We don't have an RTT for this query.  Maybe the
780                          * packet was lost, or maybe this server is very
781                          * slow.  We don't know.  Increase the RTT.
782                          */
783                         INSIST(no_response);
784                         rtt = query->addrinfo->srtt + 200000;
785                         if (rtt > 10000000)
786                                 rtt = 10000000;
787                         /*
788                          * Replace the current RTT with our value.
789                          */
790                         factor = DNS_ADB_RTTADJREPLACE;
791                 }
792                 dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor);
793         }
794
795         /* Remember that the server has been tried. */
796         if (!TRIED(query->addrinfo)) {
797                 dns_adb_changeflags(fctx->adb, query->addrinfo,
798                                     FCTX_ADDRINFO_TRIED, FCTX_ADDRINFO_TRIED);
799         }
800
801         /*
802          * Age RTTs of servers not tried.
803          */
804         factor = DNS_ADB_RTTADJAGE;
805         if (finish != NULL)
806                 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
807                      addrinfo != NULL;
808                      addrinfo = ISC_LIST_NEXT(addrinfo, publink))
809                         if (UNMARKED(addrinfo))
810                                 dns_adb_adjustsrtt(fctx->adb, addrinfo,
811                                                    0, factor);
812
813         if (finish != NULL && TRIEDFIND(fctx))
814                 for (find = ISC_LIST_HEAD(fctx->finds);
815                      find != NULL;
816                      find = ISC_LIST_NEXT(find, publink))
817                         for (addrinfo = ISC_LIST_HEAD(find->list);
818                              addrinfo != NULL;
819                              addrinfo = ISC_LIST_NEXT(addrinfo, publink))
820                                 if (UNMARKED(addrinfo))
821                                         dns_adb_adjustsrtt(fctx->adb, addrinfo,
822                                                            0, factor);
823
824         if (finish != NULL && TRIEDALT(fctx)) {
825                 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
826                      addrinfo != NULL;
827                      addrinfo = ISC_LIST_NEXT(addrinfo, publink))
828                         if (UNMARKED(addrinfo))
829                                 dns_adb_adjustsrtt(fctx->adb, addrinfo,
830                                                    0, factor);
831                 for (find = ISC_LIST_HEAD(fctx->altfinds);
832                      find != NULL;
833                      find = ISC_LIST_NEXT(find, publink))
834                         for (addrinfo = ISC_LIST_HEAD(find->list);
835                              addrinfo != NULL;
836                              addrinfo = ISC_LIST_NEXT(addrinfo, publink))
837                                 if (UNMARKED(addrinfo))
838                                         dns_adb_adjustsrtt(fctx->adb, addrinfo,
839                                                            0, factor);
840         }
841
842         /*
843          * Check for any outstanding socket events.  If they exist, cancel
844          * them and let the event handlers finish the cleanup.  The resolver
845          * only needs to worry about managing the connect and send events;
846          * the dispatcher manages the recv events.
847          */
848         if (RESQUERY_CONNECTING(query)) {
849                 /*
850                  * Cancel the connect.
851                  */
852                 if (query->tcpsocket != NULL) {
853                         isc_socket_cancel(query->tcpsocket, NULL,
854                                           ISC_SOCKCANCEL_CONNECT);
855                 } else if (query->dispentry != NULL) {
856                         INSIST(query->exclusivesocket);
857                         socket = dns_dispatch_getentrysocket(query->dispentry);
858                         if (socket != NULL)
859                                 isc_socket_cancel(socket, NULL,
860                                                   ISC_SOCKCANCEL_CONNECT);
861                 }
862         } else if (RESQUERY_SENDING(query)) {
863                 /*
864                  * Cancel the pending send.
865                  */
866                 if (query->exclusivesocket && query->dispentry != NULL)
867                         socket = dns_dispatch_getentrysocket(query->dispentry);
868                 else
869                         socket = dns_dispatch_getsocket(query->dispatch);
870                 if (socket != NULL)
871                         isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND);
872         }
873
874         if (query->dispentry != NULL)
875                 dns_dispatch_removeresponse(&query->dispentry, deventp);
876
877         ISC_LIST_UNLINK(fctx->queries, query, link);
878
879         if (query->tsig != NULL)
880                 isc_buffer_free(&query->tsig);
881
882         if (query->tsigkey != NULL)
883                 dns_tsigkey_detach(&query->tsigkey);
884
885         if (query->dispatch != NULL)
886                 dns_dispatch_detach(&query->dispatch);
887
888         if (! (RESQUERY_CONNECTING(query) || RESQUERY_SENDING(query)))
889                 /*
890                  * It's safe to destroy the query now.
891                  */
892                 resquery_destroy(&query);
893 }
894
895 static void
896 fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) {
897         resquery_t *query, *next_query;
898
899         FCTXTRACE("cancelqueries");
900
901         for (query = ISC_LIST_HEAD(fctx->queries);
902              query != NULL;
903              query = next_query) {
904                 next_query = ISC_LIST_NEXT(query, link);
905                 fctx_cancelquery(&query, NULL, NULL, no_response);
906         }
907 }
908
909 static void
910 fctx_cleanupfinds(fetchctx_t *fctx) {
911         dns_adbfind_t *find, *next_find;
912
913         REQUIRE(ISC_LIST_EMPTY(fctx->queries));
914
915         for (find = ISC_LIST_HEAD(fctx->finds);
916              find != NULL;
917              find = next_find) {
918                 next_find = ISC_LIST_NEXT(find, publink);
919                 ISC_LIST_UNLINK(fctx->finds, find, publink);
920                 dns_adb_destroyfind(&find);
921         }
922         fctx->find = NULL;
923 }
924
925 static void
926 fctx_cleanupaltfinds(fetchctx_t *fctx) {
927         dns_adbfind_t *find, *next_find;
928
929         REQUIRE(ISC_LIST_EMPTY(fctx->queries));
930
931         for (find = ISC_LIST_HEAD(fctx->altfinds);
932              find != NULL;
933              find = next_find) {
934                 next_find = ISC_LIST_NEXT(find, publink);
935                 ISC_LIST_UNLINK(fctx->altfinds, find, publink);
936                 dns_adb_destroyfind(&find);
937         }
938         fctx->altfind = NULL;
939 }
940
941 static void
942 fctx_cleanupforwaddrs(fetchctx_t *fctx) {
943         dns_adbaddrinfo_t *addr, *next_addr;
944
945         REQUIRE(ISC_LIST_EMPTY(fctx->queries));
946
947         for (addr = ISC_LIST_HEAD(fctx->forwaddrs);
948              addr != NULL;
949              addr = next_addr) {
950                 next_addr = ISC_LIST_NEXT(addr, publink);
951                 ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink);
952                 dns_adb_freeaddrinfo(fctx->adb, &addr);
953         }
954 }
955
956 static void
957 fctx_cleanupaltaddrs(fetchctx_t *fctx) {
958         dns_adbaddrinfo_t *addr, *next_addr;
959
960         REQUIRE(ISC_LIST_EMPTY(fctx->queries));
961
962         for (addr = ISC_LIST_HEAD(fctx->altaddrs);
963              addr != NULL;
964              addr = next_addr) {
965                 next_addr = ISC_LIST_NEXT(addr, publink);
966                 ISC_LIST_UNLINK(fctx->altaddrs, addr, publink);
967                 dns_adb_freeaddrinfo(fctx->adb, &addr);
968         }
969 }
970
971 static inline void
972 fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) {
973         FCTXTRACE("stopeverything");
974         fctx_cancelqueries(fctx, no_response);
975         fctx_cleanupfinds(fctx);
976         fctx_cleanupaltfinds(fctx);
977         fctx_cleanupforwaddrs(fctx);
978         fctx_cleanupaltaddrs(fctx);
979         fctx_stoptimer(fctx);
980 }
981
982 static inline void
983 fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
984         dns_fetchevent_t *event, *next_event;
985         isc_task_t *task;
986         unsigned int count = 0;
987         isc_interval_t i;
988         isc_boolean_t logit = ISC_FALSE;
989         isc_time_t now;
990         unsigned int old_spillat;
991         unsigned int new_spillat = 0;   /* initialized to silence
992                                            compiler warnings */
993
994         /*
995          * Caller must be holding the appropriate bucket lock.
996          */
997         REQUIRE(fctx->state == fetchstate_done);
998
999         FCTXTRACE("sendevents");
1000
1001         /*
1002          * Keep some record of fetch result for logging later (if required).
1003          */
1004         fctx->result = result;
1005         fctx->exitline = line;
1006         TIME_NOW(&now);
1007         fctx->duration = isc_time_microdiff(&now, &fctx->start);
1008
1009         for (event = ISC_LIST_HEAD(fctx->events);
1010              event != NULL;
1011              event = next_event) {
1012                 next_event = ISC_LIST_NEXT(event, ev_link);
1013                 ISC_LIST_UNLINK(fctx->events, event, ev_link);
1014                 task = event->ev_sender;
1015                 event->ev_sender = fctx;
1016                 if (!HAVE_ANSWER(fctx))
1017                         event->result = result;
1018
1019                 INSIST(result != ISC_R_SUCCESS ||
1020                        dns_rdataset_isassociated(event->rdataset) ||
1021                        fctx->type == dns_rdatatype_any ||
1022                        fctx->type == dns_rdatatype_rrsig ||
1023                        fctx->type == dns_rdatatype_sig);
1024
1025                 /*
1026                  * Negative results must be indicated in event->result.
1027                  */
1028                 if (dns_rdataset_isassociated(event->rdataset) &&
1029                     event->rdataset->type == dns_rdatatype_none) {
1030                         INSIST(event->result == DNS_R_NCACHENXDOMAIN ||
1031                                event->result == DNS_R_NCACHENXRRSET);
1032                 }
1033
1034                 isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event));
1035                 count++;
1036         }
1037
1038         if ((fctx->attributes & FCTX_ATTR_HAVEANSWER) != 0 &&
1039             fctx->spilled &&
1040             (count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) {
1041                 LOCK(&fctx->res->lock);
1042                 if (count == fctx->res->spillat && !fctx->res->exiting) {
1043                         old_spillat = fctx->res->spillat;
1044                         fctx->res->spillat += 5;
1045                         if (fctx->res->spillat > fctx->res->spillatmax &&
1046                             fctx->res->spillatmax != 0)
1047                                 fctx->res->spillat = fctx->res->spillatmax;
1048                         new_spillat = fctx->res->spillat;
1049                         if (new_spillat != old_spillat) {
1050                                 logit = ISC_TRUE;
1051                         }
1052                         isc_interval_set(&i, 20 * 60, 0);
1053                         result = isc_timer_reset(fctx->res->spillattimer,
1054                                                  isc_timertype_ticker, NULL,
1055                                                  &i, ISC_TRUE);
1056                         RUNTIME_CHECK(result == ISC_R_SUCCESS);
1057                 }
1058                 UNLOCK(&fctx->res->lock);
1059                 if (logit)
1060                         isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
1061                                       DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
1062                                       "clients-per-query increased to %u",
1063                                       new_spillat);
1064         }
1065 }
1066
1067 static inline void
1068 log_edns(fetchctx_t *fctx) {
1069         char domainbuf[DNS_NAME_FORMATSIZE];
1070
1071         if (fctx->reason == NULL)
1072                 return;
1073
1074         dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
1075         isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
1076                       DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
1077                       "success resolving '%s' (in '%s'?) after %s",
1078                       fctx->info, domainbuf, fctx->reason);
1079
1080         fctx->reason = NULL;
1081 }
1082
1083 static void
1084 fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
1085         dns_resolver_t *res;
1086         isc_boolean_t no_response;
1087
1088         REQUIRE(line >= 0);
1089
1090         FCTXTRACE("done");
1091
1092         res = fctx->res;
1093
1094         if (result == ISC_R_SUCCESS) {
1095                 /*%
1096                  * Log any deferred EDNS timeout messages.
1097                  */
1098                 log_edns(fctx);
1099                 no_response = ISC_TRUE;
1100          } else
1101                 no_response = ISC_FALSE;
1102
1103         fctx->reason = NULL;
1104         fctx_stopeverything(fctx, no_response);
1105
1106         LOCK(&res->buckets[fctx->bucketnum].lock);
1107
1108         fctx->state = fetchstate_done;
1109         fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
1110         fctx_sendevents(fctx, result, line);
1111
1112         UNLOCK(&res->buckets[fctx->bucketnum].lock);
1113 }
1114
1115 static void
1116 process_sendevent(resquery_t *query, isc_event_t *event) {
1117         isc_socketevent_t *sevent = (isc_socketevent_t *)event;
1118         isc_boolean_t retry = ISC_FALSE;
1119         isc_result_t result;
1120         fetchctx_t *fctx;
1121
1122         fctx = query->fctx;
1123
1124         if (RESQUERY_CANCELED(query)) {
1125                 if (query->sends == 0 && query->connects == 0) {
1126                         /*
1127                          * This query was canceled while the
1128                          * isc_socket_sendto/connect() was in progress.
1129                          */
1130                         if (query->tcpsocket != NULL)
1131                                 isc_socket_detach(&query->tcpsocket);
1132                         resquery_destroy(&query);
1133                 }
1134         } else {
1135                 switch (sevent->result) {
1136                 case ISC_R_SUCCESS:
1137                         break;
1138
1139                 case ISC_R_HOSTUNREACH:
1140                 case ISC_R_NETUNREACH:
1141                 case ISC_R_NOPERM:
1142                 case ISC_R_ADDRNOTAVAIL:
1143                 case ISC_R_CONNREFUSED:
1144
1145                         /*
1146                          * No route to remote.
1147                          */
1148                         add_bad(fctx, query->addrinfo, sevent->result,
1149                                 badns_unreachable);
1150                         fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
1151                         retry = ISC_TRUE;
1152                         break;
1153
1154                 default:
1155                         fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
1156                         break;
1157                 }
1158         }
1159
1160         isc_event_free(&event);
1161
1162         if (retry) {
1163                 /*
1164                  * Behave as if the idle timer has expired.  For TCP
1165                  * this may not actually reflect the latest timer.
1166                  */
1167                 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
1168                 result = fctx_stopidletimer(fctx);
1169                 if (result != ISC_R_SUCCESS)
1170                         fctx_done(fctx, result, __LINE__);
1171                 else
1172                         fctx_try(fctx, ISC_TRUE);
1173         }
1174 }
1175
1176 static void
1177 resquery_udpconnected(isc_task_t *task, isc_event_t *event) {
1178         resquery_t *query = event->ev_arg;
1179
1180         REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
1181
1182         QTRACE("udpconnected");
1183
1184         UNUSED(task);
1185
1186         INSIST(RESQUERY_CONNECTING(query));
1187
1188         query->connects--;
1189
1190         process_sendevent(query, event);
1191 }
1192
1193 static void
1194 resquery_senddone(isc_task_t *task, isc_event_t *event) {
1195         resquery_t *query = event->ev_arg;
1196
1197         REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1198
1199         QTRACE("senddone");
1200
1201         /*
1202          * XXXRTH
1203          *
1204          * Currently we don't wait for the senddone event before retrying
1205          * a query.  This means that if we get really behind, we may end
1206          * up doing extra work!
1207          */
1208
1209         UNUSED(task);
1210
1211         INSIST(RESQUERY_SENDING(query));
1212
1213         query->sends--;
1214
1215         process_sendevent(query, event);
1216 }
1217
1218 static inline isc_result_t
1219 fctx_addopt(dns_message_t *message, unsigned int version,
1220             isc_uint16_t udpsize, isc_boolean_t request_nsid)
1221 {
1222         dns_rdataset_t *rdataset;
1223         dns_rdatalist_t *rdatalist;
1224         dns_rdata_t *rdata;
1225         isc_result_t result;
1226
1227         rdatalist = NULL;
1228         result = dns_message_gettemprdatalist(message, &rdatalist);
1229         if (result != ISC_R_SUCCESS)
1230                 return (result);
1231         rdata = NULL;
1232         result = dns_message_gettemprdata(message, &rdata);
1233         if (result != ISC_R_SUCCESS)
1234                 return (result);
1235         rdataset = NULL;
1236         result = dns_message_gettemprdataset(message, &rdataset);
1237         if (result != ISC_R_SUCCESS)
1238                 return (result);
1239         dns_rdataset_init(rdataset);
1240
1241         rdatalist->type = dns_rdatatype_opt;
1242         rdatalist->covers = 0;
1243
1244         /*
1245          * Set Maximum UDP buffer size.
1246          */
1247         rdatalist->rdclass = udpsize;
1248
1249         /*
1250          * Set EXTENDED-RCODE and Z to 0, DO to 1.
1251          */
1252         rdatalist->ttl = (version << 16);
1253         rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
1254
1255         /*
1256          * Set EDNS options if applicable
1257          */
1258         if (request_nsid) {
1259                 /* Send empty NSID option (RFC5001) */
1260                 unsigned char data[4];
1261                 isc_buffer_t buf;
1262
1263                 isc_buffer_init(&buf, data, sizeof(data));
1264                 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
1265                 isc_buffer_putuint16(&buf, 0);
1266                 rdata->data = data;
1267                 rdata->length = sizeof(data);
1268         } else {
1269                 rdata->data = NULL;
1270                 rdata->length = 0;
1271         }
1272
1273         rdata->rdclass = rdatalist->rdclass;
1274         rdata->type = rdatalist->type;
1275         rdata->flags = 0;
1276
1277         ISC_LIST_INIT(rdatalist->rdata);
1278         ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1279         RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS);
1280
1281         return (dns_message_setopt(message, rdataset));
1282 }
1283
1284 static inline void
1285 fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
1286         unsigned int seconds;
1287         unsigned int us;
1288
1289         /*
1290          * We retry every .8 seconds the first two times through the address
1291          * list, and then we do exponential back-off.
1292          */
1293         if (fctx->restarts < 3)
1294                 us = 800000;
1295         else
1296                 us = (800000 << (fctx->restarts - 2));
1297
1298         /*
1299          * Double the round-trip time.
1300          */
1301         rtt *= 2;
1302
1303         /*
1304          * Always wait for at least the doubled round-trip time.
1305          */
1306         if (us < rtt)
1307                 us = rtt;
1308
1309         /*
1310          * But don't ever wait for more than 10 seconds.
1311          */
1312         if (us > 10000000)
1313                 us = 10000000;
1314
1315         seconds = us / 1000000;
1316         us -= seconds * 1000000;
1317         isc_interval_set(&fctx->interval, seconds, us * 1000);
1318 }
1319
1320 static isc_result_t
1321 fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
1322            unsigned int options)
1323 {
1324         dns_resolver_t *res;
1325         isc_task_t *task;
1326         isc_result_t result;
1327         resquery_t *query;
1328         isc_sockaddr_t addr;
1329         isc_boolean_t have_addr = ISC_FALSE;
1330         unsigned int srtt;
1331
1332         FCTXTRACE("query");
1333
1334         res = fctx->res;
1335         task = res->buckets[fctx->bucketnum].task;
1336
1337         srtt = addrinfo->srtt;
1338         if (ISFORWARDER(addrinfo) && srtt < 1000000)
1339                 srtt = 1000000;
1340
1341         fctx_setretryinterval(fctx, srtt);
1342         result = fctx_startidletimer(fctx, &fctx->interval);
1343         if (result != ISC_R_SUCCESS)
1344                 return (result);
1345
1346         INSIST(ISC_LIST_EMPTY(fctx->validators));
1347
1348         dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
1349
1350         query = isc_mem_get(res->buckets[fctx->bucketnum].mctx,
1351                             sizeof(*query));
1352         if (query == NULL) {
1353                 result = ISC_R_NOMEMORY;
1354                 goto stop_idle_timer;
1355         }
1356         query->mctx = res->buckets[fctx->bucketnum].mctx;
1357         query->options = options;
1358         query->attributes = 0;
1359         query->sends = 0;
1360         query->connects = 0;
1361         /*
1362          * Note that the caller MUST guarantee that 'addrinfo' will remain
1363          * valid until this query is canceled.
1364          */
1365         query->addrinfo = addrinfo;
1366         TIME_NOW(&query->start);
1367
1368         /*
1369          * If this is a TCP query, then we need to make a socket and
1370          * a dispatch for it here.  Otherwise we use the resolver's
1371          * shared dispatch.
1372          */
1373         query->dispatchmgr = res->dispatchmgr;
1374         query->dispatch = NULL;
1375         query->exclusivesocket = ISC_FALSE;
1376         query->tcpsocket = NULL;
1377         if (res->view->peers != NULL) {
1378                 dns_peer_t *peer = NULL;
1379                 isc_netaddr_t dstip;
1380                 isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr);
1381                 result = dns_peerlist_peerbyaddr(res->view->peers,
1382                                                  &dstip, &peer);
1383                 if (result == ISC_R_SUCCESS) {
1384                         result = dns_peer_getquerysource(peer, &addr);
1385                         if (result == ISC_R_SUCCESS)
1386                                 have_addr = ISC_TRUE;
1387                 }
1388         }
1389
1390         if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1391                 int pf;
1392
1393                 pf = isc_sockaddr_pf(&addrinfo->sockaddr);
1394                 if (!have_addr) {
1395                         switch (pf) {
1396                         case PF_INET:
1397                                 result =
1398                                   dns_dispatch_getlocaladdress(res->dispatchv4,
1399                                                                &addr);
1400                                 break;
1401                         case PF_INET6:
1402                                 result =
1403                                   dns_dispatch_getlocaladdress(res->dispatchv6,
1404                                                                &addr);
1405                                 break;
1406                         default:
1407                                 result = ISC_R_NOTIMPLEMENTED;
1408                                 break;
1409                         }
1410                         if (result != ISC_R_SUCCESS)
1411                                 goto cleanup_query;
1412                 }
1413                 isc_sockaddr_setport(&addr, 0);
1414
1415                 result = isc_socket_create(res->socketmgr, pf,
1416                                            isc_sockettype_tcp,
1417                                            &query->tcpsocket);
1418                 if (result != ISC_R_SUCCESS)
1419                         goto cleanup_query;
1420
1421 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
1422                 result = isc_socket_bind(query->tcpsocket, &addr, 0);
1423                 if (result != ISC_R_SUCCESS)
1424                         goto cleanup_socket;
1425 #endif
1426
1427                 /*
1428                  * A dispatch will be created once the connect succeeds.
1429                  */
1430         } else {
1431                 if (have_addr) {
1432                         unsigned int attrs, attrmask;
1433                         attrs = DNS_DISPATCHATTR_UDP;
1434                         switch (isc_sockaddr_pf(&addr)) {
1435                         case AF_INET:
1436                                 attrs |= DNS_DISPATCHATTR_IPV4;
1437                                 break;
1438                         case AF_INET6:
1439                                 attrs |= DNS_DISPATCHATTR_IPV6;
1440                                 break;
1441                         default:
1442                                 result = ISC_R_NOTIMPLEMENTED;
1443                                 goto cleanup_query;
1444                         }
1445                         attrmask = DNS_DISPATCHATTR_UDP;
1446                         attrmask |= DNS_DISPATCHATTR_TCP;
1447                         attrmask |= DNS_DISPATCHATTR_IPV4;
1448                         attrmask |= DNS_DISPATCHATTR_IPV6;
1449                         result = dns_dispatch_getudp(res->dispatchmgr,
1450                                                      res->socketmgr,
1451                                                      res->taskmgr, &addr,
1452                                                      4096, 1000, 32768, 16411,
1453                                                      16433, attrs, attrmask,
1454                                                      &query->dispatch);
1455                         if (result != ISC_R_SUCCESS)
1456                                 goto cleanup_query;
1457                 } else {
1458                         switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {
1459                         case PF_INET:
1460                                 dns_dispatch_attach(res->dispatchv4,
1461                                                     &query->dispatch);
1462                                 query->exclusivesocket = res->exclusivev4;
1463                                 break;
1464                         case PF_INET6:
1465                                 dns_dispatch_attach(res->dispatchv6,
1466                                                     &query->dispatch);
1467                                 query->exclusivesocket = res->exclusivev6;
1468                                 break;
1469                         default:
1470                                 result = ISC_R_NOTIMPLEMENTED;
1471                                 goto cleanup_query;
1472                         }
1473                 }
1474                 /*
1475                  * We should always have a valid dispatcher here.  If we
1476                  * don't support a protocol family, then its dispatcher
1477                  * will be NULL, but we shouldn't be finding addresses for
1478                  * protocol types we don't support, so the dispatcher
1479                  * we found should never be NULL.
1480                  */
1481                 INSIST(query->dispatch != NULL);
1482         }
1483
1484         query->dispentry = NULL;
1485         query->fctx = fctx;
1486         query->tsig = NULL;
1487         query->tsigkey = NULL;
1488         ISC_LINK_INIT(query, link);
1489         query->magic = QUERY_MAGIC;
1490
1491         if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1492                 /*
1493                  * Connect to the remote server.
1494                  *
1495                  * XXXRTH  Should we attach to the socket?
1496                  */
1497                 result = isc_socket_connect(query->tcpsocket,
1498                                             &addrinfo->sockaddr, task,
1499                                             resquery_connected, query);
1500                 if (result != ISC_R_SUCCESS)
1501                         goto cleanup_socket;
1502                 query->connects++;
1503                 QTRACE("connecting via TCP");
1504         } else {
1505                 result = resquery_send(query);
1506                 if (result != ISC_R_SUCCESS)
1507                         goto cleanup_dispatch;
1508         }
1509         fctx->querysent++;
1510
1511         ISC_LIST_APPEND(fctx->queries, query, link);
1512         query->fctx->nqueries++;
1513         if (isc_sockaddr_pf(&addrinfo->sockaddr) == PF_INET)
1514                 inc_stats(res, dns_resstatscounter_queryv4);
1515         else
1516                 inc_stats(res, dns_resstatscounter_queryv6);
1517         if (res->view->resquerystats != NULL)
1518                 dns_rdatatypestats_increment(res->view->resquerystats,
1519                                              fctx->type);
1520
1521         return (ISC_R_SUCCESS);
1522
1523  cleanup_socket:
1524         isc_socket_detach(&query->tcpsocket);
1525
1526  cleanup_dispatch:
1527         if (query->dispatch != NULL)
1528                 dns_dispatch_detach(&query->dispatch);
1529
1530  cleanup_query:
1531         query->magic = 0;
1532         isc_mem_put(res->buckets[fctx->bucketnum].mctx,
1533                     query, sizeof(*query));
1534
1535  stop_idle_timer:
1536         RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS);
1537
1538         return (result);
1539 }
1540
1541 static isc_boolean_t
1542 triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1543         isc_sockaddr_t *sa;
1544
1545         for (sa = ISC_LIST_HEAD(fctx->edns);
1546              sa != NULL;
1547              sa = ISC_LIST_NEXT(sa, link)) {
1548                 if (isc_sockaddr_equal(sa, address))
1549                         return (ISC_TRUE);
1550         }
1551
1552         return (ISC_FALSE);
1553 }
1554
1555 static void
1556 add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1557         isc_sockaddr_t *sa;
1558
1559         if (triededns(fctx, address))
1560                 return;
1561
1562         sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
1563                          sizeof(*sa));
1564         if (sa == NULL)
1565                 return;
1566
1567         *sa = *address;
1568         ISC_LIST_INITANDAPPEND(fctx->edns, sa, link);
1569 }
1570
1571 static isc_boolean_t
1572 triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
1573         isc_sockaddr_t *sa;
1574
1575         for (sa = ISC_LIST_HEAD(fctx->edns512);
1576              sa != NULL;
1577              sa = ISC_LIST_NEXT(sa, link)) {
1578                 if (isc_sockaddr_equal(sa, address))
1579                         return (ISC_TRUE);
1580         }
1581
1582         return (ISC_FALSE);
1583 }
1584
1585 static void
1586 add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
1587         isc_sockaddr_t *sa;
1588
1589         if (triededns512(fctx, address))
1590                 return;
1591
1592         sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
1593                          sizeof(*sa));
1594         if (sa == NULL)
1595                 return;
1596
1597         *sa = *address;
1598         ISC_LIST_INITANDAPPEND(fctx->edns512, sa, link);
1599 }
1600
1601 static isc_result_t
1602 resquery_send(resquery_t *query) {
1603         fetchctx_t *fctx;
1604         isc_result_t result;
1605         dns_name_t *qname = NULL;
1606         dns_rdataset_t *qrdataset = NULL;
1607         isc_region_t r;
1608         dns_resolver_t *res;
1609         isc_task_t *task;
1610         isc_socket_t *socket;
1611         isc_buffer_t tcpbuffer;
1612         isc_sockaddr_t *address;
1613         isc_buffer_t *buffer;
1614         isc_netaddr_t ipaddr;
1615         dns_tsigkey_t *tsigkey = NULL;
1616         dns_peer_t *peer = NULL;
1617         isc_boolean_t useedns;
1618         dns_compress_t cctx;
1619         isc_boolean_t cleanup_cctx = ISC_FALSE;
1620         isc_boolean_t secure_domain;
1621
1622         fctx = query->fctx;
1623         QTRACE("send");
1624
1625         res = fctx->res;
1626         task = res->buckets[fctx->bucketnum].task;
1627         address = NULL;
1628
1629         if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1630                 /*
1631                  * Reserve space for the TCP message length.
1632                  */
1633                 isc_buffer_init(&tcpbuffer, query->data, sizeof(query->data));
1634                 isc_buffer_init(&query->buffer, query->data + 2,
1635                                 sizeof(query->data) - 2);
1636                 buffer = &tcpbuffer;
1637         } else {
1638                 isc_buffer_init(&query->buffer, query->data,
1639                                 sizeof(query->data));
1640                 buffer = &query->buffer;
1641         }
1642
1643         result = dns_message_gettempname(fctx->qmessage, &qname);
1644         if (result != ISC_R_SUCCESS)
1645                 goto cleanup_temps;
1646         result = dns_message_gettemprdataset(fctx->qmessage, &qrdataset);
1647         if (result != ISC_R_SUCCESS)
1648                 goto cleanup_temps;
1649
1650         /*
1651          * Get a query id from the dispatch.
1652          */
1653         result = dns_dispatch_addresponse2(query->dispatch,
1654                                            &query->addrinfo->sockaddr,
1655                                            task,
1656                                            resquery_response,
1657                                            query,
1658                                            &query->id,
1659                                            &query->dispentry,
1660                                            res->socketmgr);
1661         if (result != ISC_R_SUCCESS)
1662                 goto cleanup_temps;
1663
1664         fctx->qmessage->opcode = dns_opcode_query;
1665
1666         /*
1667          * Set up question.
1668          */
1669         dns_name_init(qname, NULL);
1670         dns_name_clone(&fctx->name, qname);
1671         dns_rdataset_init(qrdataset);
1672         dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type);
1673         ISC_LIST_APPEND(qname->list, qrdataset, link);
1674         dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION);
1675         qname = NULL;
1676         qrdataset = NULL;
1677
1678         /*
1679          * Set RD if the client has requested that we do a recursive query,
1680          * or if we're sending to a forwarder.
1681          */
1682         if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0 ||
1683             ISFORWARDER(query->addrinfo))
1684                 fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD;
1685
1686         /*
1687          * Set CD if the client says don't validate or the question is
1688          * under a secure entry point.
1689          */
1690         if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
1691                 fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
1692         } else if (res->view->enablevalidation) {
1693                 result = dns_keytable_issecuredomain(res->view->secroots,
1694                                                      &fctx->name,
1695                                                      &secure_domain);
1696                 if (result != ISC_R_SUCCESS)
1697                         secure_domain = ISC_FALSE;
1698                 if (res->view->dlv != NULL)
1699                         secure_domain = ISC_TRUE;
1700                 if (secure_domain)
1701                         fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
1702         }
1703
1704         /*
1705          * We don't have to set opcode because it defaults to query.
1706          */
1707         fctx->qmessage->id = query->id;
1708
1709         /*
1710          * Convert the question to wire format.
1711          */
1712         result = dns_compress_init(&cctx, -1, fctx->res->mctx);
1713         if (result != ISC_R_SUCCESS)
1714                 goto cleanup_message;
1715         cleanup_cctx = ISC_TRUE;
1716
1717         result = dns_message_renderbegin(fctx->qmessage, &cctx,
1718                                          &query->buffer);
1719         if (result != ISC_R_SUCCESS)
1720                 goto cleanup_message;
1721
1722         result = dns_message_rendersection(fctx->qmessage,
1723                                            DNS_SECTION_QUESTION, 0);
1724         if (result != ISC_R_SUCCESS)
1725                 goto cleanup_message;
1726
1727         peer = NULL;
1728         isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr);
1729         (void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer);
1730
1731         /*
1732          * The ADB does not know about servers with "edns no".  Check this,
1733          * and then inform the ADB for future use.
1734          */
1735         if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0 &&
1736             peer != NULL &&
1737             dns_peer_getsupportedns(peer, &useedns) == ISC_R_SUCCESS &&
1738             !useedns)
1739         {
1740                 query->options |= DNS_FETCHOPT_NOEDNS0;
1741                 dns_adb_changeflags(fctx->adb, query->addrinfo,
1742                                     DNS_FETCHOPT_NOEDNS0,
1743                                     DNS_FETCHOPT_NOEDNS0);
1744         }
1745
1746         /* Sync NOEDNS0 flag in addrinfo->flags and options now. */
1747         if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0)
1748                 query->options |= DNS_FETCHOPT_NOEDNS0;
1749
1750         /*
1751          * Handle timeouts by reducing the UDP response size to 512 bytes
1752          * then if that doesn't work disabling EDNS (includes DO) and CD.
1753          *
1754          * These timeout can be due to:
1755          *      * broken nameservers that don't respond to EDNS queries.
1756          *      * broken/misconfigured firewalls and NAT implementations
1757          *        that don't handle IP fragmentation.
1758          *      * broken/misconfigured firewalls that don't handle responses
1759          *        greater than 512 bytes.
1760          *      * broken/misconfigured firewalls that don't handle EDNS, DO
1761          *        or CD.
1762          *      * packet loss / link outage.
1763          */
1764         if (fctx->timeout) {
1765                 if ((triededns512(fctx, &query->addrinfo->sockaddr) ||
1766                      fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) &&
1767                     (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
1768                         query->options |= DNS_FETCHOPT_NOEDNS0;
1769                         fctx->reason = "disabling EDNS";
1770                 } else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
1771                             fctx->timeouts >= MAX_EDNS0_TIMEOUTS) &&
1772                            (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
1773                         query->options |= DNS_FETCHOPT_EDNS512;
1774                         fctx->reason = "reducing the advertised EDNS UDP "
1775                                        "packet size to 512 octets";
1776                 }
1777                 fctx->timeout = ISC_FALSE;
1778         }
1779
1780         /*
1781          * Use EDNS0, unless the caller doesn't want it, or we know that
1782          * the remote server doesn't like it.
1783          */
1784         if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
1785                 if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
1786                         unsigned int version = 0;       /* Default version. */
1787                         unsigned int flags;
1788                         isc_uint16_t udpsize = res->udpsize;
1789                         isc_boolean_t reqnsid = res->view->requestnsid;
1790
1791                         flags = query->addrinfo->flags;
1792                         if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) {
1793                                 version = flags & DNS_FETCHOPT_EDNSVERSIONMASK;
1794                                 version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
1795                         }
1796                         if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
1797                                 udpsize = 512;
1798                         else if (peer != NULL)
1799                                 (void)dns_peer_getudpsize(peer, &udpsize);
1800
1801                         /* request NSID for current view or peer? */
1802                         if (peer != NULL)
1803                                 (void) dns_peer_getrequestnsid(peer, &reqnsid);
1804                         result = fctx_addopt(fctx->qmessage, version,
1805                                              udpsize, reqnsid);
1806                         if (reqnsid && result == ISC_R_SUCCESS) {
1807                                 query->options |= DNS_FETCHOPT_WANTNSID;
1808                         } else if (result != ISC_R_SUCCESS) {
1809                                 /*
1810                                  * We couldn't add the OPT, but we'll press on.
1811                                  * We're not using EDNS0, so set the NOEDNS0
1812                                  * bit.
1813                                  */
1814                                 query->options |= DNS_FETCHOPT_NOEDNS0;
1815                         }
1816                 } else {
1817                         /*
1818                          * We know this server doesn't like EDNS0, so we
1819                          * won't use it.  Set the NOEDNS0 bit since we're
1820                          * not using EDNS0.
1821                          */
1822                         query->options |= DNS_FETCHOPT_NOEDNS0;
1823                 }
1824         }
1825
1826         /*
1827          * If we need EDNS0 to do this query and aren't using it, we lose.
1828          */
1829         if (NEEDEDNS0(fctx) && (query->options & DNS_FETCHOPT_NOEDNS0) != 0) {
1830                 result = DNS_R_SERVFAIL;
1831                 goto cleanup_message;
1832         }
1833
1834         if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
1835                 add_triededns(fctx, &query->addrinfo->sockaddr);
1836
1837         if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
1838                 add_triededns512(fctx, &query->addrinfo->sockaddr);
1839
1840         /*
1841          * Clear CD if EDNS is not in use.
1842          */
1843         if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0)
1844                 fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD;
1845
1846         /*
1847          * Add TSIG record tailored to the current recipient.
1848          */
1849         result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey);
1850         if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1851                 goto cleanup_message;
1852
1853         if (tsigkey != NULL) {
1854                 result = dns_message_settsigkey(fctx->qmessage, tsigkey);
1855                 dns_tsigkey_detach(&tsigkey);
1856                 if (result != ISC_R_SUCCESS)
1857                         goto cleanup_message;
1858         }
1859
1860         result = dns_message_rendersection(fctx->qmessage,
1861                                            DNS_SECTION_ADDITIONAL, 0);
1862         if (result != ISC_R_SUCCESS)
1863                 goto cleanup_message;
1864
1865         result = dns_message_renderend(fctx->qmessage);
1866         if (result != ISC_R_SUCCESS)
1867                 goto cleanup_message;
1868
1869         dns_compress_invalidate(&cctx);
1870         cleanup_cctx = ISC_FALSE;
1871
1872         if (dns_message_gettsigkey(fctx->qmessage) != NULL) {
1873                 dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage),
1874                                    &query->tsigkey);
1875                 result = dns_message_getquerytsig(fctx->qmessage,
1876                                                   fctx->res->mctx,
1877                                                   &query->tsig);
1878                 if (result != ISC_R_SUCCESS)
1879                         goto cleanup_message;
1880         }
1881
1882         /*
1883          * If using TCP, write the length of the message at the beginning
1884          * of the buffer.
1885          */
1886         if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1887                 isc_buffer_usedregion(&query->buffer, &r);
1888                 isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t)r.length);
1889                 isc_buffer_add(&tcpbuffer, r.length);
1890         }
1891
1892         /*
1893          * We're now done with the query message.
1894          */
1895         dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
1896
1897         if (query->exclusivesocket)
1898                 socket = dns_dispatch_getentrysocket(query->dispentry);
1899         else
1900                 socket = dns_dispatch_getsocket(query->dispatch);
1901         /*
1902          * Send the query!
1903          */
1904         if ((query->options & DNS_FETCHOPT_TCP) == 0) {
1905                 address = &query->addrinfo->sockaddr;
1906                 if (query->exclusivesocket) {
1907                         result = isc_socket_connect(socket, address, task,
1908                                                     resquery_udpconnected,
1909                                                     query);
1910                         if (result != ISC_R_SUCCESS)
1911                                 goto cleanup_message;
1912                         query->connects++;
1913                 }
1914         }
1915         isc_buffer_usedregion(buffer, &r);
1916
1917         /*
1918          * XXXRTH  Make sure we don't send to ourselves!  We should probably
1919          *              prune out these addresses when we get them from the ADB.
1920          */
1921         result = isc_socket_sendto(socket, &r, task, resquery_senddone,
1922                                    query, address, NULL);
1923         if (result != ISC_R_SUCCESS)
1924                 goto cleanup_message;
1925
1926         query->sends++;
1927
1928         QTRACE("sent");
1929
1930         return (ISC_R_SUCCESS);
1931
1932  cleanup_message:
1933         if (cleanup_cctx)
1934                 dns_compress_invalidate(&cctx);
1935
1936         dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
1937
1938         /*
1939          * Stop the dispatcher from listening.
1940          */
1941         dns_dispatch_removeresponse(&query->dispentry, NULL);
1942
1943  cleanup_temps:
1944         if (qname != NULL)
1945                 dns_message_puttempname(fctx->qmessage, &qname);
1946         if (qrdataset != NULL)
1947                 dns_message_puttemprdataset(fctx->qmessage, &qrdataset);
1948
1949         return (result);
1950 }
1951
1952 static void
1953 resquery_connected(isc_task_t *task, isc_event_t *event) {
1954         isc_socketevent_t *sevent = (isc_socketevent_t *)event;
1955         resquery_t *query = event->ev_arg;
1956         isc_boolean_t retry = ISC_FALSE;
1957         isc_interval_t interval;
1958         isc_result_t result;
1959         unsigned int attrs;
1960         fetchctx_t *fctx;
1961
1962         REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
1963         REQUIRE(VALID_QUERY(query));
1964
1965         QTRACE("connected");
1966
1967         UNUSED(task);
1968
1969         /*
1970          * XXXRTH
1971          *
1972          * Currently we don't wait for the connect event before retrying
1973          * a query.  This means that if we get really behind, we may end
1974          * up doing extra work!
1975          */
1976
1977         query->connects--;
1978         fctx = query->fctx;
1979
1980         if (RESQUERY_CANCELED(query)) {
1981                 /*
1982                  * This query was canceled while the connect() was in
1983                  * progress.
1984                  */
1985                 isc_socket_detach(&query->tcpsocket);
1986                 resquery_destroy(&query);
1987         } else {
1988                 switch (sevent->result) {
1989                 case ISC_R_SUCCESS:
1990
1991                         /*
1992                          * Extend the idle timer for TCP.  20 seconds
1993                          * should be long enough for a TCP connection to be
1994                          * established, a single DNS request to be sent,
1995                          * and the response received.
1996                          */
1997                         isc_interval_set(&interval, 20, 0);
1998                         result = fctx_startidletimer(query->fctx, &interval);
1999                         if (result != ISC_R_SUCCESS) {
2000                                 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
2001                                 fctx_done(fctx, result, __LINE__);
2002                                 break;
2003                         }
2004                         /*
2005                          * We are connected.  Create a dispatcher and
2006                          * send the query.
2007                          */
2008                         attrs = 0;
2009                         attrs |= DNS_DISPATCHATTR_TCP;
2010                         attrs |= DNS_DISPATCHATTR_PRIVATE;
2011                         attrs |= DNS_DISPATCHATTR_CONNECTED;
2012                         if (isc_sockaddr_pf(&query->addrinfo->sockaddr) ==
2013                             AF_INET)
2014                                 attrs |= DNS_DISPATCHATTR_IPV4;
2015                         else
2016                                 attrs |= DNS_DISPATCHATTR_IPV6;
2017                         attrs |= DNS_DISPATCHATTR_MAKEQUERY;
2018
2019                         result = dns_dispatch_createtcp(query->dispatchmgr,
2020                                                      query->tcpsocket,
2021                                                      query->fctx->res->taskmgr,
2022                                                      4096, 2, 1, 1, 3, attrs,
2023                                                      &query->dispatch);
2024
2025                         /*
2026                          * Regardless of whether dns_dispatch_create()
2027                          * succeeded or not, we don't need our reference
2028                          * to the socket anymore.
2029                          */
2030                         isc_socket_detach(&query->tcpsocket);
2031
2032                         if (result == ISC_R_SUCCESS)
2033                                 result = resquery_send(query);
2034
2035                         if (result != ISC_R_SUCCESS) {
2036                                 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
2037                                 fctx_done(fctx, result, __LINE__);
2038                         }
2039                         break;
2040
2041                 case ISC_R_NETUNREACH:
2042                 case ISC_R_HOSTUNREACH:
2043                 case ISC_R_CONNREFUSED:
2044                 case ISC_R_NOPERM:
2045                 case ISC_R_ADDRNOTAVAIL:
2046                 case ISC_R_CONNECTIONRESET:
2047                         /*
2048                          * No route to remote.
2049                          */
2050                         isc_socket_detach(&query->tcpsocket);
2051                         fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
2052                         retry = ISC_TRUE;
2053                         break;
2054
2055                 default:
2056                         isc_socket_detach(&query->tcpsocket);
2057                         fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
2058                         break;
2059                 }
2060         }
2061
2062         isc_event_free(&event);
2063
2064         if (retry) {
2065                 /*
2066                  * Behave as if the idle timer has expired.  For TCP
2067                  * connections this may not actually reflect the latest timer.
2068                  */
2069                 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
2070                 result = fctx_stopidletimer(fctx);
2071                 if (result != ISC_R_SUCCESS)
2072                         fctx_done(fctx, result, __LINE__);
2073                 else
2074                         fctx_try(fctx, ISC_TRUE);
2075         }
2076 }
2077
2078 static void
2079 fctx_finddone(isc_task_t *task, isc_event_t *event) {
2080         fetchctx_t *fctx;
2081         dns_adbfind_t *find;
2082         dns_resolver_t *res;
2083         isc_boolean_t want_try = ISC_FALSE;
2084         isc_boolean_t want_done = ISC_FALSE;
2085         isc_boolean_t bucket_empty = ISC_FALSE;
2086         unsigned int bucketnum;
2087
2088         find = event->ev_sender;
2089         fctx = event->ev_arg;
2090         REQUIRE(VALID_FCTX(fctx));
2091         res = fctx->res;
2092
2093         UNUSED(task);
2094
2095         FCTXTRACE("finddone");
2096
2097         INSIST(fctx->pending > 0);
2098         fctx->pending--;
2099
2100         if (ADDRWAIT(fctx)) {
2101                 /*
2102                  * The fetch is waiting for a name to be found.
2103                  */
2104                 INSIST(!SHUTTINGDOWN(fctx));
2105                 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
2106                 if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES)
2107                         want_try = ISC_TRUE;
2108                 else {
2109                         fctx->findfail++;
2110                         if (fctx->pending == 0) {
2111                                 /*
2112                                  * We've got nothing else to wait for and don't
2113                                  * know the answer.  There's nothing to do but
2114                                  * fail the fctx.
2115                                  */
2116                                 want_done = ISC_TRUE;
2117                         }
2118                 }
2119         } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
2120                    fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
2121                 bucketnum = fctx->bucketnum;
2122                 LOCK(&res->buckets[bucketnum].lock);
2123                 /*
2124                  * Note that we had to wait until we had the lock before
2125                  * looking at fctx->references.
2126                  */
2127                 if (fctx->references == 0)
2128                         bucket_empty = fctx_destroy(fctx);
2129                 UNLOCK(&res->buckets[bucketnum].lock);
2130         }
2131
2132         isc_event_free(&event);
2133         dns_adb_destroyfind(&find);
2134
2135         if (want_try)
2136                 fctx_try(fctx, ISC_TRUE);
2137         else if (want_done)
2138                 fctx_done(fctx, ISC_R_FAILURE, __LINE__);
2139         else if (bucket_empty)
2140                 empty_bucket(res);
2141 }
2142
2143
2144 static inline isc_boolean_t
2145 bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) {
2146         isc_sockaddr_t *sa;
2147
2148         for (sa = ISC_LIST_HEAD(fctx->bad);
2149              sa != NULL;
2150              sa = ISC_LIST_NEXT(sa, link)) {
2151                 if (isc_sockaddr_equal(sa, address))
2152                         return (ISC_TRUE);
2153         }
2154
2155         return (ISC_FALSE);
2156 }
2157
2158 static inline isc_boolean_t
2159 mark_bad(fetchctx_t *fctx) {
2160         dns_adbfind_t *curr;
2161         dns_adbaddrinfo_t *addrinfo;
2162         isc_boolean_t all_bad = ISC_TRUE;
2163
2164         /*
2165          * Mark all known bad servers, so we don't try to talk to them
2166          * again.
2167          */
2168
2169         /*
2170          * Mark any bad nameservers.
2171          */
2172         for (curr = ISC_LIST_HEAD(fctx->finds);
2173              curr != NULL;
2174              curr = ISC_LIST_NEXT(curr, publink)) {
2175                 for (addrinfo = ISC_LIST_HEAD(curr->list);
2176                      addrinfo != NULL;
2177                      addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2178                         if (bad_server(fctx, &addrinfo->sockaddr))
2179                                 addrinfo->flags |= FCTX_ADDRINFO_MARK;
2180                         else
2181                                 all_bad = ISC_FALSE;
2182                 }
2183         }
2184
2185         /*
2186          * Mark any bad forwarders.
2187          */
2188         for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
2189              addrinfo != NULL;
2190              addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2191                 if (bad_server(fctx, &addrinfo->sockaddr))
2192                         addrinfo->flags |= FCTX_ADDRINFO_MARK;
2193                 else
2194                         all_bad = ISC_FALSE;
2195         }
2196
2197         /*
2198          * Mark any bad alternates.
2199          */
2200         for (curr = ISC_LIST_HEAD(fctx->altfinds);
2201              curr != NULL;
2202              curr = ISC_LIST_NEXT(curr, publink)) {
2203                 for (addrinfo = ISC_LIST_HEAD(curr->list);
2204                      addrinfo != NULL;
2205                      addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2206                         if (bad_server(fctx, &addrinfo->sockaddr))
2207                                 addrinfo->flags |= FCTX_ADDRINFO_MARK;
2208                         else
2209                                 all_bad = ISC_FALSE;
2210                 }
2211         }
2212
2213         for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
2214              addrinfo != NULL;
2215              addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2216                 if (bad_server(fctx, &addrinfo->sockaddr))
2217                         addrinfo->flags |= FCTX_ADDRINFO_MARK;
2218                 else
2219                         all_bad = ISC_FALSE;
2220         }
2221
2222         return (all_bad);
2223 }
2224
2225 static void
2226 add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
2227         badnstype_t badtype)
2228 {
2229         char namebuf[DNS_NAME_FORMATSIZE];
2230         char addrbuf[ISC_SOCKADDR_FORMATSIZE];
2231         char classbuf[64];
2232         char typebuf[64];
2233         char code[64];
2234         isc_buffer_t b;
2235         isc_sockaddr_t *sa;
2236         const char *sep1, *sep2;
2237         isc_sockaddr_t *address = &addrinfo->sockaddr;
2238
2239         if (reason == DNS_R_LAME)
2240                 fctx->lamecount++;
2241         else {
2242                 switch (badtype) {
2243                 case badns_unreachable:
2244                         fctx->neterr++;
2245                         break;
2246                 case badns_response:
2247                         fctx->badresp++;
2248                         break;
2249                 case badns_validation:
2250                         break;  /* counted as 'valfail' */
2251                 }
2252         }
2253
2254         if (bad_server(fctx, address)) {
2255                 /*
2256                  * We already know this server is bad.
2257                  */
2258                 return;
2259         }
2260
2261         FCTXTRACE("add_bad");
2262
2263         sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx,
2264                          sizeof(*sa));
2265         if (sa == NULL)
2266                 return;
2267         *sa = *address;
2268         ISC_LIST_INITANDAPPEND(fctx->bad, sa, link);
2269
2270         if (reason == DNS_R_LAME)       /* already logged */
2271                 return;
2272
2273         if (reason == DNS_R_UNEXPECTEDRCODE &&
2274             fctx->rmessage->rcode == dns_rcode_servfail &&
2275             ISFORWARDER(addrinfo))
2276                 return;
2277
2278         if (reason == DNS_R_UNEXPECTEDRCODE) {
2279                 isc_buffer_init(&b, code, sizeof(code) - 1);
2280                 dns_rcode_totext(fctx->rmessage->rcode, &b);
2281                 code[isc_buffer_usedlength(&b)] = '\0';
2282                 sep1 = "(";
2283                 sep2 = ") ";
2284         } else if (reason == DNS_R_UNEXPECTEDOPCODE) {
2285                 isc_buffer_init(&b, code, sizeof(code) - 1);
2286                 dns_opcode_totext((dns_opcode_t)fctx->rmessage->opcode, &b);
2287                 code[isc_buffer_usedlength(&b)] = '\0';
2288                 sep1 = "(";
2289                 sep2 = ") ";
2290         } else {
2291                 code[0] = '\0';
2292                 sep1 = "";
2293                 sep2 = "";
2294         }
2295         dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
2296         dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
2297         dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf));
2298         isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));
2299         isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
2300                       DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
2301                       "%s %s%s%sresolving '%s/%s/%s': %s",
2302                       dns_result_totext(reason), sep1, code, sep2,
2303                       namebuf, typebuf, classbuf, addrbuf);
2304 }
2305
2306 /*
2307  * Return 'bits' bits of random entropy from fctx->rand_buf,
2308  * refreshing it by calling isc_random_get() whenever the requested
2309  * number of bits is greater than the number in the buffer.
2310  */
2311 static inline isc_uint32_t
2312 random_bits(fetchctx_t *fctx, isc_uint32_t bits) {
2313         isc_uint32_t ret = 0;
2314
2315         REQUIRE(VALID_FCTX(fctx));
2316         REQUIRE(bits <= 32);
2317         if (bits == 0)
2318                 return (0);
2319
2320         if (bits >= fctx->rand_bits) {
2321                 /* if rand_bits == 0, this is unnecessary but harmless */
2322                 bits -= fctx->rand_bits;
2323                 ret = fctx->rand_buf << bits;
2324
2325                 /* refresh random buffer now */
2326                 isc_random_get(&fctx->rand_buf);
2327                 fctx->rand_bits = sizeof(fctx->rand_buf) * CHAR_BIT;
2328         }
2329
2330         if (bits > 0) {
2331                 isc_uint32_t mask = 0xffffffff;
2332                 if (bits < 32) {
2333                         mask = (1 << bits) - 1;
2334                 }
2335
2336                 ret |= fctx->rand_buf & mask;
2337                 fctx->rand_buf >>= bits;
2338                 fctx->rand_bits -= bits;
2339         }
2340
2341         return (ret);
2342 }
2343
2344 /*
2345  * Add some random jitter to a server's RTT value so that the
2346  * order of queries will be unpredictable.
2347  *
2348  * RTT values of servers which have been tried are fuzzed by 128 ms.
2349  * Servers that haven't been tried yet have their RTT set to a random
2350  * value between 0 ms and 7 ms; they should get to go first, but in
2351  * unpredictable order.
2352  */
2353 static inline void
2354 randomize_srtt(fetchctx_t *fctx, dns_adbaddrinfo_t *ai) {
2355         if (TRIED(ai)) {
2356                 ai->srtt >>= 10; /* convert to milliseconds, near enough */
2357                 ai->srtt |= (ai->srtt & 0x80) | random_bits(fctx, 7);
2358                 ai->srtt <<= 10; /* now back to microseconds */
2359         } else
2360                 ai->srtt = random_bits(fctx, 3) << 10;
2361 }
2362
2363 /*
2364  * Sort addrinfo list by RTT (with random jitter)
2365  */
2366 static void
2367 sort_adbfind(fetchctx_t *fctx, dns_adbfind_t *find) {
2368         dns_adbaddrinfo_t *best, *curr;
2369         dns_adbaddrinfolist_t sorted;
2370
2371         /* Add jitter to SRTT values */
2372         curr = ISC_LIST_HEAD(find->list);
2373         while (curr != NULL) {
2374                 randomize_srtt(fctx, curr);
2375                 curr = ISC_LIST_NEXT(curr, publink);
2376         }
2377
2378         /* Lame N^2 bubble sort. */
2379         ISC_LIST_INIT(sorted);
2380         while (!ISC_LIST_EMPTY(find->list)) {
2381                 best = ISC_LIST_HEAD(find->list);
2382                 curr = ISC_LIST_NEXT(best, publink);
2383                 while (curr != NULL) {
2384                         if (curr->srtt < best->srtt)
2385                                 best = curr;
2386                         curr = ISC_LIST_NEXT(curr, publink);
2387                 }
2388                 ISC_LIST_UNLINK(find->list, best, publink);
2389                 ISC_LIST_APPEND(sorted, best, publink);
2390         }
2391         find->list = sorted;
2392 }
2393
2394 /*
2395  * Sort a list of finds by server RTT (with random jitter)
2396  */
2397 static void
2398 sort_finds(fetchctx_t *fctx, dns_adbfindlist_t *findlist) {
2399         dns_adbfind_t *best, *curr;
2400         dns_adbfindlist_t sorted;
2401         dns_adbaddrinfo_t *addrinfo, *bestaddrinfo;
2402
2403         /* Sort each find's addrinfo list by SRTT (after adding jitter) */
2404         for (curr = ISC_LIST_HEAD(*findlist);
2405              curr != NULL;
2406              curr = ISC_LIST_NEXT(curr, publink))
2407                 sort_adbfind(fctx, curr);
2408
2409         /* Lame N^2 bubble sort. */
2410         ISC_LIST_INIT(sorted);
2411         while (!ISC_LIST_EMPTY(*findlist)) {
2412                 best = ISC_LIST_HEAD(*findlist);
2413                 bestaddrinfo = ISC_LIST_HEAD(best->list);
2414                 INSIST(bestaddrinfo != NULL);
2415                 curr = ISC_LIST_NEXT(best, publink);
2416                 while (curr != NULL) {
2417                         addrinfo = ISC_LIST_HEAD(curr->list);
2418                         INSIST(addrinfo != NULL);
2419                         if (addrinfo->srtt < bestaddrinfo->srtt) {
2420                                 best = curr;
2421                                 bestaddrinfo = addrinfo;
2422                         }
2423                         curr = ISC_LIST_NEXT(curr, publink);
2424                 }
2425                 ISC_LIST_UNLINK(*findlist, best, publink);
2426                 ISC_LIST_APPEND(sorted, best, publink);
2427         }
2428         *findlist = sorted;
2429 }
2430
2431 static void
2432 findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
2433          unsigned int options, unsigned int flags, isc_stdtime_t now,
2434          isc_boolean_t *need_alternate)
2435 {
2436         dns_adbaddrinfo_t *ai;
2437         dns_adbfind_t *find;
2438         dns_resolver_t *res;
2439         isc_boolean_t unshared;
2440         isc_result_t result;
2441
2442         res = fctx->res;
2443         unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0);
2444         /*
2445          * If this name is a subdomain of the query domain, tell
2446          * the ADB to start looking using zone/hint data. This keeps us
2447          * from getting stuck if the nameserver is beneath the zone cut
2448          * and we don't know its address (e.g. because the A record has
2449          * expired).
2450          */
2451         if (dns_name_issubdomain(name, &fctx->domain))
2452                 options |= DNS_ADBFIND_STARTATZONE;
2453         options |= DNS_ADBFIND_GLUEOK;
2454         options |= DNS_ADBFIND_HINTOK;
2455
2456         /*
2457          * See what we know about this address.
2458          */
2459         find = NULL;
2460         result = dns_adb_createfind(fctx->adb,
2461                                     res->buckets[fctx->bucketnum].task,
2462                                     fctx_finddone, fctx, name,
2463                                     &fctx->name, fctx->type,
2464                                     options, now, NULL,
2465                                     res->view->dstport, &find);
2466         if (result != ISC_R_SUCCESS) {
2467                 if (result == DNS_R_ALIAS) {
2468                         /*
2469                          * XXXRTH  Follow the CNAME/DNAME chain?
2470                          */
2471                         dns_adb_destroyfind(&find);
2472                         fctx->adberr++;
2473                 }
2474         } else if (!ISC_LIST_EMPTY(find->list)) {
2475                 /*
2476                  * We have at least some of the addresses for the
2477                  * name.
2478                  */
2479                 INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0);
2480                 if (flags != 0 || port != 0) {
2481                         for (ai = ISC_LIST_HEAD(find->list);
2482                              ai != NULL;
2483                              ai = ISC_LIST_NEXT(ai, publink)) {
2484                                 ai->flags |= flags;
2485                                 if (port != 0)
2486                                         isc_sockaddr_setport(&ai->sockaddr,
2487                                                              port);
2488                         }
2489                 }
2490                 if ((flags & FCTX_ADDRINFO_FORWARDER) != 0)
2491                         ISC_LIST_APPEND(fctx->altfinds, find, publink);
2492                 else
2493                         ISC_LIST_APPEND(fctx->finds, find, publink);
2494         } else {
2495                 /*
2496                  * We don't know any of the addresses for this
2497                  * name.
2498                  */
2499                 if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) {
2500                         /*
2501                          * We're looking for them and will get an
2502                          * event about it later.
2503                          */
2504                         fctx->pending++;
2505                         /*
2506                          * Bootstrap.
2507                          */
2508                         if (need_alternate != NULL &&
2509                             !*need_alternate && unshared &&
2510                             ((res->dispatchv4 == NULL &&
2511                               find->result_v6 != DNS_R_NXDOMAIN) ||
2512                              (res->dispatchv6 == NULL &&
2513                               find->result_v4 != DNS_R_NXDOMAIN)))
2514                                 *need_alternate = ISC_TRUE;
2515                 } else {
2516                         if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0)
2517                                 fctx->lamecount++; /* cached lame server */
2518                         else
2519                                 fctx->adberr++; /* unreachable server, etc. */
2520
2521                         /*
2522                          * If we know there are no addresses for
2523                          * the family we are using then try to add
2524                          * an alternative server.
2525                          */
2526                         if (need_alternate != NULL && !*need_alternate &&
2527                             ((res->dispatchv4 == NULL &&
2528                               find->result_v6 == DNS_R_NXRRSET) ||
2529                              (res->dispatchv6 == NULL &&
2530                               find->result_v4 == DNS_R_NXRRSET)))
2531                                 *need_alternate = ISC_TRUE;
2532                         dns_adb_destroyfind(&find);
2533                 }
2534         }
2535 }
2536
2537 static isc_result_t
2538 fctx_getaddresses(fetchctx_t *fctx) {
2539         dns_rdata_t rdata = DNS_RDATA_INIT;
2540         isc_result_t result;
2541         dns_resolver_t *res;
2542         isc_stdtime_t now;
2543         unsigned int stdoptions;
2544         isc_sockaddr_t *sa;
2545         dns_adbaddrinfo_t *ai;
2546         isc_boolean_t all_bad;
2547         dns_rdata_ns_t ns;
2548         isc_boolean_t need_alternate = ISC_FALSE;
2549
2550         FCTXTRACE("getaddresses");
2551
2552         /*
2553          * Don't pound on remote servers.  (Failsafe!)
2554          */
2555         fctx->restarts++;
2556         if (fctx->restarts > 10) {
2557                 FCTXTRACE("too many restarts");
2558                 return (DNS_R_SERVFAIL);
2559         }
2560
2561         res = fctx->res;
2562         stdoptions = 0;         /* Keep compiler happy. */
2563
2564         /*
2565          * Forwarders.
2566          */
2567
2568         INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));
2569         INSIST(ISC_LIST_EMPTY(fctx->altaddrs));
2570
2571         /*
2572          * If this fctx has forwarders, use them; otherwise use any
2573          * selective forwarders specified in the view; otherwise use the
2574          * resolver's forwarders (if any).
2575          */
2576         sa = ISC_LIST_HEAD(fctx->forwarders);
2577         if (sa == NULL) {
2578                 dns_forwarders_t *forwarders = NULL;
2579                 dns_name_t *name = &fctx->name;
2580                 dns_name_t suffix;
2581                 unsigned int labels;
2582
2583                 /*
2584                  * DS records are found in the parent server.
2585                  * Strip label to get the correct forwarder (if any).
2586                  */
2587                 if (fctx->type == dns_rdatatype_ds &&
2588                     dns_name_countlabels(name) > 1) {
2589                         dns_name_init(&suffix, NULL);
2590                         labels = dns_name_countlabels(name);
2591                         dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
2592                         name = &suffix;
2593                 }
2594                 result = dns_fwdtable_find(fctx->res->view->fwdtable, name,
2595                                            &forwarders);
2596                 if (result == ISC_R_SUCCESS) {
2597                         sa = ISC_LIST_HEAD(forwarders->addrs);
2598                         fctx->fwdpolicy = forwarders->fwdpolicy;
2599                 }
2600         }
2601
2602         while (sa != NULL) {
2603                 if ((isc_sockaddr_pf(sa) == AF_INET &&
2604                          fctx->res->dispatchv4 == NULL) ||
2605                     (isc_sockaddr_pf(sa) == AF_INET6 &&
2606                         fctx->res->dispatchv6 == NULL)) {
2607                                 sa = ISC_LIST_NEXT(sa, link);
2608                                 continue;
2609                 }
2610                 ai = NULL;
2611                 result = dns_adb_findaddrinfo(fctx->adb,
2612                                               sa, &ai, 0);  /* XXXMLG */
2613                 if (result == ISC_R_SUCCESS) {
2614                         dns_adbaddrinfo_t *cur;
2615                         ai->flags |= FCTX_ADDRINFO_FORWARDER;
2616                         cur = ISC_LIST_HEAD(fctx->forwaddrs);
2617                         while (cur != NULL && cur->srtt < ai->srtt)
2618                                 cur = ISC_LIST_NEXT(cur, publink);
2619                         if (cur != NULL)
2620                                 ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur,
2621                                                       ai, publink);
2622                         else
2623                                 ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
2624                 }
2625                 sa = ISC_LIST_NEXT(sa, link);
2626         }
2627
2628         /*
2629          * If the forwarding policy is "only", we don't need the addresses
2630          * of the nameservers.
2631          */
2632         if (fctx->fwdpolicy == dns_fwdpolicy_only)
2633                 goto out;
2634
2635         /*
2636          * Normal nameservers.
2637          */
2638
2639         stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT;
2640         if (fctx->restarts == 1) {
2641                 /*
2642                  * To avoid sending out a flood of queries likely to
2643                  * result in NXRRSET, we suppress fetches for address
2644                  * families we don't have the first time through,
2645                  * provided that we have addresses in some family we
2646                  * can use.
2647                  *
2648                  * We don't want to set this option all the time, since
2649                  * if fctx->restarts > 1, we've clearly been having trouble
2650                  * with the addresses we had, so getting more could help.
2651                  */
2652                 stdoptions |= DNS_ADBFIND_AVOIDFETCHES;
2653         }
2654         if (res->dispatchv4 != NULL)
2655                 stdoptions |= DNS_ADBFIND_INET;
2656         if (res->dispatchv6 != NULL)
2657                 stdoptions |= DNS_ADBFIND_INET6;
2658         isc_stdtime_get(&now);
2659
2660         INSIST(ISC_LIST_EMPTY(fctx->finds));
2661         INSIST(ISC_LIST_EMPTY(fctx->altfinds));
2662
2663         for (result = dns_rdataset_first(&fctx->nameservers);
2664              result == ISC_R_SUCCESS;
2665              result = dns_rdataset_next(&fctx->nameservers))
2666         {
2667                 dns_rdataset_current(&fctx->nameservers, &rdata);
2668                 /*
2669                  * Extract the name from the NS record.
2670                  */
2671                 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2672                 if (result != ISC_R_SUCCESS)
2673                         continue;
2674
2675                 findname(fctx, &ns.name, 0, stdoptions, 0, now,
2676                          &need_alternate);
2677                 dns_rdata_reset(&rdata);
2678                 dns_rdata_freestruct(&ns);
2679         }
2680         if (result != ISC_R_NOMORE)
2681                 return (result);
2682
2683         /*
2684          * Do we need to use 6 to 4?
2685          */
2686         if (need_alternate) {
2687                 int family;
2688                 alternate_t *a;
2689                 family = (res->dispatchv6 != NULL) ? AF_INET6 : AF_INET;
2690                 for (a = ISC_LIST_HEAD(fctx->res->alternates);
2691                      a != NULL;
2692                      a = ISC_LIST_NEXT(a, link)) {
2693                         if (!a->isaddress) {
2694                                 findname(fctx, &a->_u._n.name, a->_u._n.port,
2695                                          stdoptions, FCTX_ADDRINFO_FORWARDER,
2696                                          now, NULL);
2697                                 continue;
2698                         }
2699                         if (isc_sockaddr_pf(&a->_u.addr) != family)
2700                                 continue;
2701                         ai = NULL;
2702                         result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr,
2703                                                       &ai, 0);
2704                         if (result == ISC_R_SUCCESS) {
2705                                 dns_adbaddrinfo_t *cur;
2706                                 ai->flags |= FCTX_ADDRINFO_FORWARDER;
2707                                 cur = ISC_LIST_HEAD(fctx->altaddrs);
2708                                 while (cur != NULL && cur->srtt < ai->srtt)
2709                                         cur = ISC_LIST_NEXT(cur, publink);
2710                                 if (cur != NULL)
2711                                         ISC_LIST_INSERTBEFORE(fctx->altaddrs,
2712                                                               cur, ai, publink);
2713                                 else
2714                                         ISC_LIST_APPEND(fctx->altaddrs, ai,
2715                                                         publink);
2716                         }
2717                 }
2718         }
2719
2720  out:
2721         /*
2722          * Mark all known bad servers.
2723          */
2724         all_bad = mark_bad(fctx);
2725
2726         /*
2727          * How are we doing?
2728          */
2729         if (all_bad) {
2730                 /*
2731                  * We've got no addresses.
2732                  */
2733                 if (fctx->pending > 0) {
2734                         /*
2735                          * We're fetching the addresses, but don't have any
2736                          * yet.   Tell the caller to wait for an answer.
2737                          */
2738                         result = DNS_R_WAIT;
2739                 } else {
2740                         /*
2741                          * We've lost completely.  We don't know any
2742                          * addresses, and the ADB has told us it can't get
2743                          * them.
2744                          */
2745                         FCTXTRACE("no addresses");
2746                         result = ISC_R_FAILURE;
2747                 }
2748         } else {
2749                 /*
2750                  * We've found some addresses.  We might still be looking
2751                  * for more addresses.
2752                  */
2753                 sort_finds(fctx, &fctx->finds);
2754                 sort_finds(fctx, &fctx->altfinds);
2755                 result = ISC_R_SUCCESS;
2756         }
2757
2758         return (result);
2759 }
2760
2761 static inline void
2762 possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr)
2763 {
2764         isc_netaddr_t na;
2765         char buf[ISC_NETADDR_FORMATSIZE];
2766         isc_sockaddr_t *sa;
2767         isc_boolean_t aborted = ISC_FALSE;
2768         isc_boolean_t bogus;
2769         dns_acl_t *blackhole;
2770         isc_netaddr_t ipaddr;
2771         dns_peer_t *peer = NULL;
2772         dns_resolver_t *res;
2773         const char *msg = NULL;
2774
2775         sa = &addr->sockaddr;
2776
2777         res = fctx->res;
2778         isc_netaddr_fromsockaddr(&ipaddr, sa);
2779         blackhole = dns_dispatchmgr_getblackhole(res->dispatchmgr);
2780         (void) dns_peerlist_peerbyaddr(res->view->peers, &ipaddr, &peer);
2781
2782         if (blackhole != NULL) {
2783                 int match;
2784
2785                 if (dns_acl_match(&ipaddr, NULL, blackhole,
2786                                   &res->view->aclenv,
2787                                   &match, NULL) == ISC_R_SUCCESS &&
2788                     match > 0)
2789                         aborted = ISC_TRUE;
2790         }
2791
2792         if (peer != NULL &&
2793             dns_peer_getbogus(peer, &bogus) == ISC_R_SUCCESS &&
2794             bogus)
2795                 aborted = ISC_TRUE;
2796
2797         if (aborted) {
2798                 addr->flags |= FCTX_ADDRINFO_MARK;
2799                 msg = "ignoring blackholed / bogus server: ";
2800         } else if (isc_sockaddr_ismulticast(sa)) {
2801                 addr->flags |= FCTX_ADDRINFO_MARK;
2802                 msg = "ignoring multicast address: ";
2803         } else if (isc_sockaddr_isexperimental(sa)) {
2804                 addr->flags |= FCTX_ADDRINFO_MARK;
2805                 msg = "ignoring experimental address: ";
2806         } else if (sa->type.sa.sa_family != AF_INET6) {
2807                 return;
2808         } else if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) {
2809                 addr->flags |= FCTX_ADDRINFO_MARK;
2810                 msg = "ignoring IPv6 mapped IPV4 address: ";
2811         } else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) {
2812                 addr->flags |= FCTX_ADDRINFO_MARK;
2813                 msg = "ignoring IPv6 compatibility IPV4 address: ";
2814         } else
2815                 return;
2816
2817         if (!isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3)))
2818                 return;
2819
2820         isc_netaddr_fromsockaddr(&na, sa);
2821         isc_netaddr_format(&na, buf, sizeof(buf));
2822         FCTXTRACE2(msg, buf);
2823 }
2824
2825 static inline dns_adbaddrinfo_t *
2826 fctx_nextaddress(fetchctx_t *fctx) {
2827         dns_adbfind_t *find, *start;
2828         dns_adbaddrinfo_t *addrinfo;
2829         dns_adbaddrinfo_t *faddrinfo;
2830
2831         /*
2832          * Return the next untried address, if any.
2833          */
2834
2835         /*
2836          * Find the first unmarked forwarder (if any).
2837          */
2838         for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
2839              addrinfo != NULL;
2840              addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2841                 if (!UNMARKED(addrinfo))
2842                         continue;
2843                 possibly_mark(fctx, addrinfo);
2844                 if (UNMARKED(addrinfo)) {
2845                         addrinfo->flags |= FCTX_ADDRINFO_MARK;
2846                         fctx->find = NULL;
2847                         return (addrinfo);
2848                 }
2849         }
2850
2851         /*
2852          * No forwarders.  Move to the next find.
2853          */
2854
2855         fctx->attributes |= FCTX_ATTR_TRIEDFIND;
2856
2857         find = fctx->find;
2858         if (find == NULL)
2859                 find = ISC_LIST_HEAD(fctx->finds);
2860         else {
2861                 find = ISC_LIST_NEXT(find, publink);
2862                 if (find == NULL)
2863                         find = ISC_LIST_HEAD(fctx->finds);
2864         }
2865
2866         /*
2867          * Find the first unmarked addrinfo.
2868          */
2869         addrinfo = NULL;
2870         if (find != NULL) {
2871                 start = find;
2872                 do {
2873                         for (addrinfo = ISC_LIST_HEAD(find->list);
2874                              addrinfo != NULL;
2875                              addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2876                                 if (!UNMARKED(addrinfo))
2877                                         continue;
2878                                 possibly_mark(fctx, addrinfo);
2879                                 if (UNMARKED(addrinfo)) {
2880                                         addrinfo->flags |= FCTX_ADDRINFO_MARK;
2881                                         break;
2882                                 }
2883                         }
2884                         if (addrinfo != NULL)
2885                                 break;
2886                         find = ISC_LIST_NEXT(find, publink);
2887                         if (find == NULL)
2888                                 find = ISC_LIST_HEAD(fctx->finds);
2889                 } while (find != start);
2890         }
2891
2892         fctx->find = find;
2893         if (addrinfo != NULL)
2894                 return (addrinfo);
2895
2896         /*
2897          * No nameservers left.  Try alternates.
2898          */
2899
2900         fctx->attributes |= FCTX_ATTR_TRIEDALT;
2901
2902         find = fctx->altfind;
2903         if (find == NULL)
2904                 find = ISC_LIST_HEAD(fctx->altfinds);
2905         else {
2906                 find = ISC_LIST_NEXT(find, publink);
2907                 if (find == NULL)
2908                         find = ISC_LIST_HEAD(fctx->altfinds);
2909         }
2910
2911         /*
2912          * Find the first unmarked addrinfo.
2913          */
2914         addrinfo = NULL;
2915         if (find != NULL) {
2916                 start = find;
2917                 do {
2918                         for (addrinfo = ISC_LIST_HEAD(find->list);
2919                              addrinfo != NULL;
2920                              addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2921                                 if (!UNMARKED(addrinfo))
2922                                         continue;
2923                                 possibly_mark(fctx, addrinfo);
2924                                 if (UNMARKED(addrinfo)) {
2925                                         addrinfo->flags |= FCTX_ADDRINFO_MARK;
2926                                         break;
2927                                 }
2928                         }
2929                         if (addrinfo != NULL)
2930                                 break;
2931                         find = ISC_LIST_NEXT(find, publink);
2932                         if (find == NULL)
2933                                 find = ISC_LIST_HEAD(fctx->altfinds);
2934                 } while (find != start);
2935         }
2936
2937         faddrinfo = addrinfo;
2938
2939         /*
2940          * See if we have a better alternate server by address.
2941          */
2942
2943         for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
2944              addrinfo != NULL;
2945              addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2946                 if (!UNMARKED(addrinfo))
2947                         continue;
2948                 possibly_mark(fctx, addrinfo);
2949                 if (UNMARKED(addrinfo) &&
2950                     (faddrinfo == NULL ||
2951                      addrinfo->srtt < faddrinfo->srtt)) {
2952                         if (faddrinfo != NULL)
2953                                 faddrinfo->flags &= ~FCTX_ADDRINFO_MARK;
2954                         addrinfo->flags |= FCTX_ADDRINFO_MARK;
2955                         break;
2956                 }
2957         }
2958
2959         if (addrinfo == NULL) {
2960                 addrinfo = faddrinfo;
2961                 fctx->altfind = find;
2962         }
2963
2964         return (addrinfo);
2965 }
2966
2967 static void
2968 fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) {
2969         isc_result_t result;
2970         dns_adbaddrinfo_t *addrinfo;
2971
2972         FCTXTRACE("try");
2973
2974         REQUIRE(!ADDRWAIT(fctx));
2975
2976         addrinfo = fctx_nextaddress(fctx);
2977         if (addrinfo == NULL) {
2978                 /*
2979                  * We have no more addresses.  Start over.
2980                  */
2981                 fctx_cancelqueries(fctx, ISC_TRUE);
2982                 fctx_cleanupfinds(fctx);
2983                 fctx_cleanupaltfinds(fctx);
2984                 fctx_cleanupforwaddrs(fctx);
2985                 fctx_cleanupaltaddrs(fctx);
2986                 result = fctx_getaddresses(fctx);
2987                 if (result == DNS_R_WAIT) {
2988                         /*
2989                          * Sleep waiting for addresses.
2990                          */
2991                         FCTXTRACE("addrwait");
2992                         fctx->attributes |= FCTX_ATTR_ADDRWAIT;
2993                         return;
2994                 } else if (result != ISC_R_SUCCESS) {
2995                         /*
2996                          * Something bad happened.
2997                          */
2998                         fctx_done(fctx, result, __LINE__);
2999                         return;
3000                 }
3001
3002                 addrinfo = fctx_nextaddress(fctx);
3003                 /*
3004                  * While we may have addresses from the ADB, they
3005                  * might be bad ones.  In this case, return SERVFAIL.
3006                  */
3007                 if (addrinfo == NULL) {
3008                         fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
3009                         return;
3010                 }
3011         }
3012
3013         result = fctx_query(fctx, addrinfo, fctx->options);
3014         if (result != ISC_R_SUCCESS)
3015                 fctx_done(fctx, result, __LINE__);
3016         else if (retrying)
3017                 inc_stats(fctx->res, dns_resstatscounter_retry);
3018 }
3019
3020 static isc_boolean_t
3021 fctx_destroy(fetchctx_t *fctx) {
3022         dns_resolver_t *res;
3023         unsigned int bucketnum;
3024         isc_sockaddr_t *sa, *next_sa;
3025
3026         /*
3027          * Caller must be holding the bucket lock.
3028          */
3029
3030         REQUIRE(VALID_FCTX(fctx));
3031         REQUIRE(fctx->state == fetchstate_done ||
3032                 fctx->state == fetchstate_init);
3033         REQUIRE(ISC_LIST_EMPTY(fctx->events));
3034         REQUIRE(ISC_LIST_EMPTY(fctx->queries));
3035         REQUIRE(ISC_LIST_EMPTY(fctx->finds));
3036         REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
3037         REQUIRE(fctx->pending == 0);
3038         REQUIRE(fctx->references == 0);
3039         REQUIRE(ISC_LIST_EMPTY(fctx->validators));
3040
3041         FCTXTRACE("destroy");
3042
3043         res = fctx->res;
3044         bucketnum = fctx->bucketnum;
3045
3046         ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
3047
3048         /*
3049          * Free bad.
3050          */
3051         for (sa = ISC_LIST_HEAD(fctx->bad);
3052              sa != NULL;
3053              sa = next_sa) {
3054                 next_sa = ISC_LIST_NEXT(sa, link);
3055                 ISC_LIST_UNLINK(fctx->bad, sa, link);
3056                 isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa));
3057         }
3058
3059         for (sa = ISC_LIST_HEAD(fctx->edns);
3060              sa != NULL;
3061              sa = next_sa) {
3062                 next_sa = ISC_LIST_NEXT(sa, link);
3063                 ISC_LIST_UNLINK(fctx->edns, sa, link);
3064                 isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa));
3065         }
3066
3067         for (sa = ISC_LIST_HEAD(fctx->edns512);
3068              sa != NULL;
3069              sa = next_sa) {
3070                 next_sa = ISC_LIST_NEXT(sa, link);
3071                 ISC_LIST_UNLINK(fctx->edns512, sa, link);
3072                 isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa));
3073         }
3074
3075         isc_timer_detach(&fctx->timer);
3076         dns_message_destroy(&fctx->rmessage);
3077         dns_message_destroy(&fctx->qmessage);
3078         if (dns_name_countlabels(&fctx->domain) > 0)
3079                 dns_name_free(&fctx->domain, res->buckets[bucketnum].mctx);
3080         if (dns_rdataset_isassociated(&fctx->nameservers))
3081                 dns_rdataset_disassociate(&fctx->nameservers);
3082         dns_name_free(&fctx->name, res->buckets[bucketnum].mctx);
3083         dns_db_detach(&fctx->cache);
3084         dns_adb_detach(&fctx->adb);
3085         isc_mem_free(res->buckets[bucketnum].mctx, fctx->info);
3086         isc_mem_put(res->buckets[bucketnum].mctx, fctx, sizeof(*fctx));
3087
3088         LOCK(&res->nlock);
3089         res->nfctx--;
3090         UNLOCK(&res->nlock);
3091
3092         if (res->buckets[bucketnum].exiting &&
3093             ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs))
3094                 return (ISC_TRUE);
3095
3096         return (ISC_FALSE);
3097 }
3098
3099 /*
3100  * Fetch event handlers.
3101  */
3102
3103 static void
3104 fctx_timeout(isc_task_t *task, isc_event_t *event) {
3105         fetchctx_t *fctx = event->ev_arg;
3106         isc_timerevent_t *tevent = (isc_timerevent_t *)event;
3107         resquery_t *query;
3108
3109         REQUIRE(VALID_FCTX(fctx));
3110
3111         UNUSED(task);
3112
3113         FCTXTRACE("timeout");
3114
3115         inc_stats(fctx->res, dns_resstatscounter_querytimeout);
3116
3117         if (event->ev_type == ISC_TIMEREVENT_LIFE) {
3118                 fctx->reason = NULL;
3119                 fctx_done(fctx, ISC_R_TIMEDOUT, __LINE__);
3120         } else {
3121                 isc_result_t result;
3122
3123                 fctx->timeouts++;
3124                 fctx->timeout = ISC_TRUE;
3125                 /*
3126                  * We could cancel the running queries here, or we could let
3127                  * them keep going.  Since we normally use separate sockets for
3128                  * different queries, we adopt the former approach to reduce
3129                  * the number of open sockets: cancel the oldest query if it
3130                  * expired after the query had started (this is usually the
3131                  * case but is not always so, depending on the task schedule
3132                  * timing).
3133                  */
3134                 query = ISC_LIST_HEAD(fctx->queries);
3135                 if (query != NULL &&
3136                     isc_time_compare(&tevent->due, &query->start) >= 0) {
3137                         fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
3138                 }
3139                 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
3140                 /*
3141                  * Our timer has triggered.  Reestablish the fctx lifetime
3142                  * timer.
3143                  */
3144                 result = fctx_starttimer(fctx);
3145                 if (result != ISC_R_SUCCESS)
3146                         fctx_done(fctx, result, __LINE__);
3147                 else
3148                         /*
3149                          * Keep trying.
3150                          */
3151                         fctx_try(fctx, ISC_TRUE);
3152         }
3153
3154         isc_event_free(&event);
3155 }
3156
3157 static void
3158 fctx_shutdown(fetchctx_t *fctx) {
3159         isc_event_t *cevent;
3160
3161         /*
3162          * Start the shutdown process for fctx, if it isn't already underway.
3163          */
3164
3165         FCTXTRACE("shutdown");
3166
3167         /*
3168          * The caller must be holding the appropriate bucket lock.
3169          */
3170
3171         if (fctx->want_shutdown)
3172                 return;
3173
3174         fctx->want_shutdown = ISC_TRUE;
3175
3176         /*
3177          * Unless we're still initializing (in which case the
3178          * control event is still outstanding), we need to post
3179          * the control event to tell the fetch we want it to
3180          * exit.
3181          */
3182         if (fctx->state != fetchstate_init) {
3183                 cevent = &fctx->control_event;
3184                 isc_task_send(fctx->res->buckets[fctx->bucketnum].task,
3185                               &cevent);
3186         }
3187 }
3188
3189 static void
3190 fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
3191         fetchctx_t *fctx = event->ev_arg;
3192         isc_boolean_t bucket_empty = ISC_FALSE;
3193         dns_resolver_t *res;
3194         unsigned int bucketnum;
3195         dns_validator_t *validator;
3196
3197         REQUIRE(VALID_FCTX(fctx));
3198
3199         UNUSED(task);
3200
3201         res = fctx->res;
3202         bucketnum = fctx->bucketnum;
3203
3204         FCTXTRACE("doshutdown");
3205
3206         /*
3207          * An fctx that is shutting down is no longer in ADDRWAIT mode.
3208          */
3209         fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
3210
3211         /*
3212          * Cancel all pending validators.  Note that this must be done
3213          * without the bucket lock held, since that could cause deadlock.
3214          */
3215         validator = ISC_LIST_HEAD(fctx->validators);
3216         while (validator != NULL) {
3217                 dns_validator_cancel(validator);
3218                 validator = ISC_LIST_NEXT(validator, link);
3219         }
3220
3221         if (fctx->nsfetch != NULL)
3222                 dns_resolver_cancelfetch(fctx->nsfetch);
3223
3224         /*
3225          * Shut down anything that is still running on behalf of this
3226          * fetch.  To avoid deadlock with the ADB, we must do this
3227          * before we lock the bucket lock.
3228          */
3229         fctx_stopeverything(fctx, ISC_FALSE);
3230
3231         LOCK(&res->buckets[bucketnum].lock);
3232
3233         fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN;
3234
3235         INSIST(fctx->state == fetchstate_active ||
3236                fctx->state == fetchstate_done);
3237         INSIST(fctx->want_shutdown);
3238
3239         if (fctx->state != fetchstate_done) {
3240                 fctx->state = fetchstate_done;
3241                 fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
3242         }
3243
3244         if (fctx->references == 0 && fctx->pending == 0 &&
3245             fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators))
3246                 bucket_empty = fctx_destroy(fctx);
3247
3248         UNLOCK(&res->buckets[bucketnum].lock);
3249
3250         if (bucket_empty)
3251                 empty_bucket(res);
3252 }
3253
3254 static void
3255 fctx_start(isc_task_t *task, isc_event_t *event) {
3256         fetchctx_t *fctx = event->ev_arg;
3257         isc_boolean_t done = ISC_FALSE, bucket_empty = ISC_FALSE;
3258         dns_resolver_t *res;
3259         unsigned int bucketnum;
3260
3261         REQUIRE(VALID_FCTX(fctx));
3262
3263         UNUSED(task);
3264
3265         res = fctx->res;
3266         bucketnum = fctx->bucketnum;
3267
3268         FCTXTRACE("start");
3269
3270         LOCK(&res->buckets[bucketnum].lock);
3271
3272         INSIST(fctx->state == fetchstate_init);
3273         if (fctx->want_shutdown) {
3274                 /*
3275                  * We haven't started this fctx yet, and we've been requested
3276                  * to shut it down.
3277                  */
3278                 fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN;
3279                 fctx->state = fetchstate_done;
3280                 fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
3281                 /*
3282                  * Since we haven't started, we INSIST that we have no
3283                  * pending ADB finds and no pending validations.
3284                  */
3285                 INSIST(fctx->pending == 0);
3286                 INSIST(fctx->nqueries == 0);
3287                 INSIST(ISC_LIST_EMPTY(fctx->validators));
3288                 if (fctx->references == 0) {
3289                         /*
3290                          * It's now safe to destroy this fctx.
3291                          */
3292                         bucket_empty = fctx_destroy(fctx);
3293                 }
3294                 done = ISC_TRUE;
3295         } else {
3296                 /*
3297                  * Normal fctx startup.
3298                  */
3299                 fctx->state = fetchstate_active;
3300                 /*
3301                  * Reset the control event for later use in shutting down
3302                  * the fctx.
3303                  */
3304                 ISC_EVENT_INIT(event, sizeof(*event), 0, NULL,
3305                                DNS_EVENT_FETCHCONTROL, fctx_doshutdown, fctx,
3306                                NULL, NULL, NULL);
3307         }
3308
3309         UNLOCK(&res->buckets[bucketnum].lock);
3310
3311         if (!done) {
3312                 isc_result_t result;
3313
3314                 /*
3315                  * All is well.  Start working on the fetch.
3316                  */
3317                 result = fctx_starttimer(fctx);
3318                 if (result != ISC_R_SUCCESS)
3319                         fctx_done(fctx, result, __LINE__);
3320                 else
3321                         fctx_try(fctx, ISC_FALSE);
3322         } else if (bucket_empty)
3323                 empty_bucket(res);
3324 }
3325
3326 /*
3327  * Fetch Creation, Joining, and Cancelation.
3328  */
3329
3330 static inline isc_result_t
3331 fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client,
3332           dns_messageid_t id, isc_taskaction_t action, void *arg,
3333           dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
3334           dns_fetch_t *fetch)
3335 {
3336         isc_task_t *clone;
3337         dns_fetchevent_t *event;
3338
3339         FCTXTRACE("join");
3340
3341         /*
3342          * We store the task we're going to send this event to in the
3343          * sender field.  We'll make the fetch the sender when we actually
3344          * send the event.
3345          */
3346         clone = NULL;
3347         isc_task_attach(task, &clone);
3348         event = (dns_fetchevent_t *)
3349                 isc_event_allocate(fctx->res->mctx, clone, DNS_EVENT_FETCHDONE,
3350                                    action, arg, sizeof(*event));
3351         if (event == NULL) {
3352                 isc_task_detach(&clone);
3353                 return (ISC_R_NOMEMORY);
3354         }
3355         event->result = DNS_R_SERVFAIL;
3356         event->qtype = fctx->type;
3357         event->db = NULL;
3358         event->node = NULL;
3359         event->rdataset = rdataset;
3360         event->sigrdataset = sigrdataset;
3361         event->fetch = fetch;
3362         event->client = client;
3363         event->id = id;
3364         dns_fixedname_init(&event->foundname);
3365
3366         /*
3367          * Make sure that we can store the sigrdataset in the
3368          * first event if it is needed by any of the events.
3369          */
3370         if (event->sigrdataset != NULL)
3371                 ISC_LIST_PREPEND(fctx->events, event, ev_link);
3372         else
3373                 ISC_LIST_APPEND(fctx->events, event, ev_link);
3374         fctx->references++;
3375
3376         fetch->magic = DNS_FETCH_MAGIC;
3377         fetch->private = fctx;
3378
3379         return (ISC_R_SUCCESS);
3380 }
3381
3382 static isc_result_t
3383 fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
3384             dns_name_t *domain, dns_rdataset_t *nameservers,
3385             unsigned int options, unsigned int bucketnum, fetchctx_t **fctxp)
3386 {
3387         fetchctx_t *fctx;
3388         isc_result_t result;
3389         isc_result_t iresult;
3390         isc_interval_t interval;
3391         dns_fixedname_t fixed;
3392         unsigned int findoptions = 0;
3393         char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
3394         char typebuf[DNS_RDATATYPE_FORMATSIZE];
3395         dns_name_t suffix;
3396
3397         /*
3398          * Caller must be holding the lock for bucket number 'bucketnum'.
3399          */
3400         REQUIRE(fctxp != NULL && *fctxp == NULL);
3401
3402         fctx = isc_mem_get(res->buckets[bucketnum].mctx, sizeof(*fctx));
3403         if (fctx == NULL)
3404                 return (ISC_R_NOMEMORY);
3405         dns_name_format(name, buf, sizeof(buf));
3406         dns_rdatatype_format(type, typebuf, sizeof(typebuf));
3407         strcat(buf, "/");       /* checked */
3408         strcat(buf, typebuf);   /* checked */
3409         fctx->info = isc_mem_strdup(res->buckets[bucketnum].mctx, buf);
3410         if (fctx->info == NULL) {
3411                 result = ISC_R_NOMEMORY;
3412                 goto cleanup_fetch;
3413         }
3414         FCTXTRACE("create");
3415         dns_name_init(&fctx->name, NULL);
3416         result = dns_name_dup(name, res->buckets[bucketnum].mctx, &fctx->name);
3417         if (result != ISC_R_SUCCESS)
3418                 goto cleanup_info;
3419         dns_name_init(&fctx->domain, NULL);
3420         dns_rdataset_init(&fctx->nameservers);
3421
3422         fctx->type = type;
3423         fctx->options = options;
3424         /*
3425          * Note!  We do not attach to the task.  We are relying on the
3426          * resolver to ensure that this task doesn't go away while we are
3427          * using it.
3428          */
3429         fctx->res = res;
3430         fctx->references = 0;
3431         fctx->bucketnum = bucketnum;
3432         fctx->state = fetchstate_init;
3433         fctx->want_shutdown = ISC_FALSE;
3434         fctx->cloned = ISC_FALSE;
3435         ISC_LIST_INIT(fctx->queries);
3436         ISC_LIST_INIT(fctx->finds);
3437         ISC_LIST_INIT(fctx->altfinds);
3438         ISC_LIST_INIT(fctx->forwaddrs);
3439         ISC_LIST_INIT(fctx->altaddrs);
3440         ISC_LIST_INIT(fctx->forwarders);
3441         fctx->fwdpolicy = dns_fwdpolicy_none;
3442         ISC_LIST_INIT(fctx->bad);
3443         ISC_LIST_INIT(fctx->edns);
3444         ISC_LIST_INIT(fctx->edns512);
3445         ISC_LIST_INIT(fctx->validators);
3446         fctx->validator = NULL;
3447         fctx->find = NULL;
3448         fctx->altfind = NULL;
3449         fctx->pending = 0;
3450         fctx->restarts = 0;
3451         fctx->querysent = 0;
3452         fctx->referrals = 0;
3453         TIME_NOW(&fctx->start);
3454         fctx->timeouts = 0;
3455         fctx->lamecount = 0;
3456         fctx->adberr = 0;
3457         fctx->neterr = 0;
3458         fctx->badresp = 0;
3459         fctx->findfail = 0;
3460         fctx->valfail = 0;
3461         fctx->result = ISC_R_FAILURE;
3462         fctx->vresult = ISC_R_SUCCESS;
3463         fctx->exitline = -1;    /* sentinel */
3464         fctx->logged = ISC_FALSE;
3465         fctx->attributes = 0;
3466         fctx->spilled = ISC_FALSE;
3467         fctx->nqueries = 0;
3468         fctx->reason = NULL;
3469         fctx->rand_buf = 0;
3470         fctx->rand_bits = 0;
3471         fctx->timeout = ISC_FALSE;
3472
3473         dns_name_init(&fctx->nsname, NULL);
3474         fctx->nsfetch = NULL;
3475         dns_rdataset_init(&fctx->nsrrset);
3476
3477         if (domain == NULL) {
3478                 dns_forwarders_t *forwarders = NULL;
3479                 unsigned int labels;
3480
3481                 /*
3482                  * DS records are found in the parent server.
3483                  * Strip label to get the correct forwarder (if any).
3484                  */
3485                 if (fctx->type == dns_rdatatype_ds &&
3486                     dns_name_countlabels(name) > 1) {
3487                         dns_name_init(&suffix, NULL);
3488                         labels = dns_name_countlabels(name);
3489                         dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
3490                         name = &suffix;
3491                 }
3492                 dns_fixedname_init(&fixed);
3493                 domain = dns_fixedname_name(&fixed);
3494                 result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
3495                                             domain, &forwarders);
3496                 if (result == ISC_R_SUCCESS)
3497                         fctx->fwdpolicy = forwarders->fwdpolicy;
3498
3499                 if (fctx->fwdpolicy != dns_fwdpolicy_only) {
3500                         /*
3501                          * The caller didn't supply a query domain and
3502                          * nameservers, and we're not in forward-only mode,
3503                          * so find the best nameservers to use.
3504                          */
3505                         if (dns_rdatatype_atparent(type))
3506                                 findoptions |= DNS_DBFIND_NOEXACT;
3507                         result = dns_view_findzonecut(res->view, name, domain,
3508                                                       0, findoptions, ISC_TRUE,
3509                                                       &fctx->nameservers,
3510                                                       NULL);
3511                         if (result != ISC_R_SUCCESS)
3512                                 goto cleanup_name;
3513                         result = dns_name_dup(domain,
3514                                               res->buckets[bucketnum].mctx,
3515                                               &fctx->domain);
3516                         if (result != ISC_R_SUCCESS) {
3517                                 dns_rdataset_disassociate(&fctx->nameservers);
3518                                 goto cleanup_name;
3519                         }
3520                 } else {
3521                         /*
3522                          * We're in forward-only mode.  Set the query domain.
3523                          */
3524                         result = dns_name_dup(domain,
3525                                               res->buckets[bucketnum].mctx,
3526                                               &fctx->domain);
3527                         if (result != ISC_R_SUCCESS)
3528                                 goto cleanup_name;
3529                 }
3530         } else {
3531                 result = dns_name_dup(domain,
3532                                       res->buckets[bucketnum].mctx,
3533                                       &fctx->domain);
3534                 if (result != ISC_R_SUCCESS)
3535                         goto cleanup_name;
3536                 dns_rdataset_clone(nameservers, &fctx->nameservers);
3537         }
3538
3539         INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain));
3540
3541         fctx->qmessage = NULL;
3542         result = dns_message_create(res->buckets[bucketnum].mctx,
3543                                     DNS_MESSAGE_INTENTRENDER,
3544                                     &fctx->qmessage);
3545
3546         if (result != ISC_R_SUCCESS)
3547                 goto cleanup_domain;
3548
3549         fctx->rmessage = NULL;
3550         result = dns_message_create(res->buckets[bucketnum].mctx,
3551                                     DNS_MESSAGE_INTENTPARSE,
3552                                     &fctx->rmessage);
3553
3554         if (result != ISC_R_SUCCESS)
3555                 goto cleanup_qmessage;
3556
3557         /*
3558          * Compute an expiration time for the entire fetch.
3559          */
3560         isc_interval_set(&interval, 30, 0);             /* XXXRTH constant */
3561         iresult = isc_time_nowplusinterval(&fctx->expires, &interval);
3562         if (iresult != ISC_R_SUCCESS) {
3563                 UNEXPECTED_ERROR(__FILE__, __LINE__,
3564                                  "isc_time_nowplusinterval: %s",
3565                                  isc_result_totext(iresult));
3566                 result = ISC_R_UNEXPECTED;
3567                 goto cleanup_rmessage;
3568         }
3569
3570         /*
3571          * Default retry interval initialization.  We set the interval now
3572          * mostly so it won't be uninitialized.  It will be set to the
3573          * correct value before a query is issued.
3574          */
3575         isc_interval_set(&fctx->interval, 2, 0);
3576
3577         /*
3578          * Create an inactive timer.  It will be made active when the fetch
3579          * is actually started.
3580          */
3581         fctx->timer = NULL;
3582         iresult = isc_timer_create(res->timermgr, isc_timertype_inactive,
3583                                    NULL, NULL,
3584                                    res->buckets[bucketnum].task, fctx_timeout,
3585                                    fctx, &fctx->timer);
3586         if (iresult != ISC_R_SUCCESS) {
3587                 UNEXPECTED_ERROR(__FILE__, __LINE__,
3588                                  "isc_timer_create: %s",
3589                                  isc_result_totext(iresult));
3590                 result = ISC_R_UNEXPECTED;
3591                 goto cleanup_rmessage;
3592         }
3593
3594         /*
3595          * Attach to the view's cache and adb.
3596          */
3597         fctx->cache = NULL;
3598         dns_db_attach(res->view->cachedb, &fctx->cache);
3599         fctx->adb = NULL;
3600         dns_adb_attach(res->view->adb, &fctx->adb);
3601
3602         ISC_LIST_INIT(fctx->events);
3603         ISC_LINK_INIT(fctx, link);
3604         fctx->magic = FCTX_MAGIC;
3605
3606         ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link);
3607
3608         LOCK(&res->nlock);
3609         res->nfctx++;
3610         UNLOCK(&res->nlock);
3611
3612         *fctxp = fctx;
3613
3614         return (ISC_R_SUCCESS);
3615
3616  cleanup_rmessage:
3617         dns_message_destroy(&fctx->rmessage);
3618
3619  cleanup_qmessage:
3620         dns_message_destroy(&fctx->qmessage);
3621
3622  cleanup_domain:
3623         if (dns_name_countlabels(&fctx->domain) > 0)
3624                 dns_name_free(&fctx->domain, res->buckets[bucketnum].mctx);
3625         if (dns_rdataset_isassociated(&fctx->nameservers))
3626                 dns_rdataset_disassociate(&fctx->nameservers);
3627
3628  cleanup_name:
3629         dns_name_free(&fctx->name, res->buckets[bucketnum].mctx);
3630
3631  cleanup_info:
3632         isc_mem_free(res->buckets[bucketnum].mctx, fctx->info);
3633
3634  cleanup_fetch:
3635         isc_mem_put(res->buckets[bucketnum].mctx, fctx, sizeof(*fctx));
3636
3637         return (result);
3638 }
3639
3640 /*
3641  * Handle Responses
3642  */
3643 static inline isc_boolean_t
3644 is_lame(fetchctx_t *fctx) {
3645         dns_message_t *message = fctx->rmessage;
3646         dns_name_t *name;
3647         dns_rdataset_t *rdataset;
3648         isc_result_t result;
3649
3650         if (message->rcode != dns_rcode_noerror &&
3651             message->rcode != dns_rcode_nxdomain)
3652                 return (ISC_FALSE);
3653
3654         if (message->counts[DNS_SECTION_ANSWER] != 0)
3655                 return (ISC_FALSE);
3656
3657         if (message->counts[DNS_SECTION_AUTHORITY] == 0)
3658                 return (ISC_FALSE);
3659
3660         result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
3661         while (result == ISC_R_SUCCESS) {
3662                 name = NULL;
3663                 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
3664                 for (rdataset = ISC_LIST_HEAD(name->list);
3665                      rdataset != NULL;
3666                      rdataset = ISC_LIST_NEXT(rdataset, link)) {
3667                         dns_namereln_t namereln;
3668                         int order;
3669                         unsigned int labels;
3670                         if (rdataset->type != dns_rdatatype_ns)
3671                                 continue;
3672                         namereln = dns_name_fullcompare(name, &fctx->domain,
3673                                                         &order, &labels);
3674                         if (namereln == dns_namereln_equal &&
3675                             (message->flags & DNS_MESSAGEFLAG_AA) != 0)
3676                                 return (ISC_FALSE);
3677                         if (namereln == dns_namereln_subdomain)
3678                                 return (ISC_FALSE);
3679                         return (ISC_TRUE);
3680                 }
3681                 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
3682         }
3683
3684         return (ISC_FALSE);
3685 }
3686
3687 static inline void
3688 log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) {
3689         char namebuf[DNS_NAME_FORMATSIZE];
3690         char domainbuf[DNS_NAME_FORMATSIZE];
3691         char addrbuf[ISC_SOCKADDR_FORMATSIZE];
3692
3693         dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
3694         dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
3695         isc_sockaddr_format(&addrinfo->sockaddr, addrbuf, sizeof(addrbuf));
3696         isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
3697                       DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
3698                       "lame server resolving '%s' (in '%s'?): %s",
3699                       namebuf, domainbuf, addrbuf);
3700 }
3701
3702 static inline isc_result_t
3703 same_question(fetchctx_t *fctx) {
3704         isc_result_t result;
3705         dns_message_t *message = fctx->rmessage;
3706         dns_name_t *name;
3707         dns_rdataset_t *rdataset;
3708
3709         /*
3710          * Caller must be holding the fctx lock.
3711          */
3712
3713         /*
3714          * XXXRTH  Currently we support only one question.
3715          */
3716         if (message->counts[DNS_SECTION_QUESTION] != 1)
3717                 return (DNS_R_FORMERR);
3718
3719         result = dns_message_firstname(message, DNS_SECTION_QUESTION);
3720         if (result != ISC_R_SUCCESS)
3721                 return (result);
3722         name = NULL;
3723         dns_message_currentname(message, DNS_SECTION_QUESTION, &name);
3724         rdataset = ISC_LIST_HEAD(name->list);
3725         INSIST(rdataset != NULL);
3726         INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);
3727         if (fctx->type != rdataset->type ||
3728             fctx->res->rdclass != rdataset->rdclass ||
3729             !dns_name_equal(&fctx->name, name))
3730                 return (DNS_R_FORMERR);
3731
3732         return (ISC_R_SUCCESS);
3733 }
3734
3735 static void
3736 clone_results(fetchctx_t *fctx) {
3737         dns_fetchevent_t *event, *hevent;
3738         isc_result_t result;
3739         dns_name_t *name, *hname;
3740
3741         FCTXTRACE("clone_results");
3742
3743         /*
3744          * Set up any other events to have the same data as the first
3745          * event.
3746          *
3747          * Caller must be holding the appropriate lock.
3748          */
3749
3750         fctx->cloned = ISC_TRUE;
3751         hevent = ISC_LIST_HEAD(fctx->events);
3752         if (hevent == NULL)
3753                 return;
3754         hname = dns_fixedname_name(&hevent->foundname);
3755         for (event = ISC_LIST_NEXT(hevent, ev_link);
3756              event != NULL;
3757              event = ISC_LIST_NEXT(event, ev_link)) {
3758                 name = dns_fixedname_name(&event->foundname);
3759                 result = dns_name_copy(hname, name, NULL);
3760                 if (result != ISC_R_SUCCESS)
3761                         event->result = result;
3762                 else
3763                         event->result = hevent->result;
3764                 dns_db_attach(hevent->db, &event->db);
3765                 dns_db_attachnode(hevent->db, hevent->node, &event->node);
3766                 INSIST(hevent->rdataset != NULL);
3767                 INSIST(event->rdataset != NULL);
3768                 if (dns_rdataset_isassociated(hevent->rdataset))
3769                         dns_rdataset_clone(hevent->rdataset, event->rdataset);
3770                 INSIST(! (hevent->sigrdataset == NULL &&
3771                           event->sigrdataset != NULL));
3772                 if (hevent->sigrdataset != NULL &&
3773                     dns_rdataset_isassociated(hevent->sigrdataset) &&
3774                     event->sigrdataset != NULL)
3775                         dns_rdataset_clone(hevent->sigrdataset,
3776                                            event->sigrdataset);
3777         }
3778 }
3779
3780 #define CACHE(r)        (((r)->attributes & DNS_RDATASETATTR_CACHE) != 0)
3781 #define ANSWER(r)       (((r)->attributes & DNS_RDATASETATTR_ANSWER) != 0)
3782 #define ANSWERSIG(r)    (((r)->attributes & DNS_RDATASETATTR_ANSWERSIG) != 0)
3783 #define EXTERNAL(r)     (((r)->attributes & DNS_RDATASETATTR_EXTERNAL) != 0)
3784 #define CHAINING(r)     (((r)->attributes & DNS_RDATASETATTR_CHAINING) != 0)
3785 #define CHASE(r)        (((r)->attributes & DNS_RDATASETATTR_CHASE) != 0)
3786 #define CHECKNAMES(r)   (((r)->attributes & DNS_RDATASETATTR_CHECKNAMES) != 0)
3787
3788
3789 /*
3790  * Destroy '*fctx' if it is ready to be destroyed (i.e., if it has
3791  * no references and is no longer waiting for any events).  If this
3792  * was the last fctx in the resolver, destroy the resolver.
3793  *
3794  * Requires:
3795  *      '*fctx' is shutting down.
3796  */
3797 static void
3798 maybe_destroy(fetchctx_t *fctx) {
3799         unsigned int bucketnum;
3800         isc_boolean_t bucket_empty = ISC_FALSE;
3801         dns_resolver_t *res = fctx->res;
3802         dns_validator_t *validator, *next_validator;
3803
3804         REQUIRE(SHUTTINGDOWN(fctx));
3805
3806         if (fctx->pending != 0 || fctx->nqueries != 0)
3807                 return;
3808
3809         for (validator = ISC_LIST_HEAD(fctx->validators);
3810              validator != NULL; validator = next_validator) {
3811                 next_validator = ISC_LIST_NEXT(validator, link);
3812                 dns_validator_cancel(validator);
3813                 /*
3814                  * If this is a active validator wait for the cancel
3815                  * to complete before calling dns_validator_destroy().
3816                  */
3817                 if (validator == fctx->validator)
3818                         continue;
3819                 ISC_LIST_UNLINK(fctx->validators, validator, link);
3820                 dns_validator_destroy(&validator);
3821         }
3822
3823         bucketnum = fctx->bucketnum;
3824         LOCK(&res->buckets[bucketnum].lock);
3825         if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators))
3826                 bucket_empty = fctx_destroy(fctx);
3827         UNLOCK(&res->buckets[bucketnum].lock);
3828
3829         if (bucket_empty)
3830                 empty_bucket(res);
3831 }
3832
3833 /*
3834  * The validator has finished.
3835  */
3836 static void
3837 validated(isc_task_t *task, isc_event_t *event) {
3838         isc_result_t result = ISC_R_SUCCESS;
3839         isc_result_t eresult = ISC_R_SUCCESS;
3840         isc_stdtime_t now;
3841         fetchctx_t *fctx;
3842         dns_validatorevent_t *vevent;
3843         dns_fetchevent_t *hevent;
3844         dns_rdataset_t *ardataset = NULL;
3845         dns_rdataset_t *asigrdataset = NULL;
3846         dns_dbnode_t *node = NULL;
3847         isc_boolean_t negative;
3848         isc_boolean_t chaining;
3849         isc_boolean_t sentresponse;
3850         isc_uint32_t ttl;
3851         dns_dbnode_t *nsnode = NULL;
3852         dns_name_t *name;
3853         dns_rdataset_t *rdataset;
3854         dns_rdataset_t *sigrdataset;
3855         dns_valarg_t *valarg;
3856         dns_adbaddrinfo_t *addrinfo;
3857
3858         UNUSED(task); /* for now */
3859
3860         REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
3861         valarg = event->ev_arg;
3862         fctx = valarg->fctx;
3863         addrinfo = valarg->addrinfo;
3864         REQUIRE(VALID_FCTX(fctx));
3865         REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
3866
3867         vevent = (dns_validatorevent_t *)event;
3868
3869         FCTXTRACE("received validation completion event");
3870
3871         ISC_LIST_UNLINK(fctx->validators, vevent->validator, link);
3872         fctx->validator = NULL;
3873
3874         /*
3875          * Destroy the validator early so that we can
3876          * destroy the fctx if necessary.
3877          */
3878         dns_validator_destroy(&vevent->validator);
3879         isc_mem_put(fctx->res->buckets[fctx->bucketnum].mctx,
3880                     valarg, sizeof(*valarg));
3881
3882         negative = ISC_TF(vevent->rdataset == NULL);
3883
3884         sentresponse = ISC_TF((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0);
3885
3886         /*
3887          * If shutting down, ignore the results.  Check to see if we're
3888          * done waiting for validator completions and ADB pending events; if
3889          * so, destroy the fctx.
3890          */
3891         if (SHUTTINGDOWN(fctx) && !sentresponse) {
3892                 maybe_destroy(fctx);    /* Locks bucket. */
3893                 goto cleanup_event;
3894         }
3895
3896         LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
3897
3898         /*
3899          * If chaining, we need to make sure that the right result code is
3900          * returned, and that the rdatasets are bound.
3901          */
3902         if (vevent->result == ISC_R_SUCCESS &&
3903             !negative &&
3904             vevent->rdataset != NULL &&
3905             CHAINING(vevent->rdataset))
3906         {
3907                 if (vevent->rdataset->type == dns_rdatatype_cname)
3908                         eresult = DNS_R_CNAME;
3909                 else {
3910                         INSIST(vevent->rdataset->type == dns_rdatatype_dname);
3911                         eresult = DNS_R_DNAME;
3912                 }
3913                 chaining = ISC_TRUE;
3914         } else
3915                 chaining = ISC_FALSE;
3916
3917         /*
3918          * Either we're not shutting down, or we are shutting down but want
3919          * to cache the result anyway (if this was a validation started by
3920          * a query with cd set)
3921          */
3922
3923         hevent = ISC_LIST_HEAD(fctx->events);
3924         if (hevent != NULL) {
3925                 if (!negative && !chaining &&
3926                     (fctx->type == dns_rdatatype_any ||
3927                      fctx->type == dns_rdatatype_rrsig ||
3928                      fctx->type == dns_rdatatype_sig)) {
3929                         /*
3930                          * Don't bind rdatasets; the caller
3931                          * will iterate the node.
3932                          */
3933                 } else {
3934                         ardataset = hevent->rdataset;
3935                         asigrdataset = hevent->sigrdataset;
3936                 }
3937         }
3938
3939         if (vevent->result != ISC_R_SUCCESS) {
3940                 FCTXTRACE("validation failed");
3941                 inc_stats(fctx->res, dns_resstatscounter_valfail);
3942                 fctx->valfail++;
3943                 fctx->vresult = vevent->result;
3944                 result = ISC_R_NOTFOUND;
3945                 if (vevent->rdataset != NULL)
3946                         result = dns_db_findnode(fctx->cache, vevent->name,
3947                                                  ISC_TRUE, &node);
3948                 if (result == ISC_R_SUCCESS)
3949                         (void)dns_db_deleterdataset(fctx->cache, node, NULL,
3950                                                     vevent->type, 0);
3951                 if (result == ISC_R_SUCCESS && vevent->sigrdataset != NULL)
3952                         (void)dns_db_deleterdataset(fctx->cache, node, NULL,
3953                                                     dns_rdatatype_rrsig,
3954                                                     vevent->type);
3955                 if (result == ISC_R_SUCCESS)
3956                         dns_db_detachnode(fctx->cache, &node);
3957                 result = vevent->result;
3958                 add_bad(fctx, addrinfo, result, badns_validation);
3959                 isc_event_free(&event);
3960                 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
3961                 INSIST(fctx->validator == NULL);
3962                 fctx->validator = ISC_LIST_HEAD(fctx->validators);
3963                 if (fctx->validator != NULL) {
3964                         dns_validator_send(fctx->validator);
3965                 } else if (sentresponse)
3966                         fctx_done(fctx, result, __LINE__); /* Locks bucket. */
3967                 else
3968                         fctx_try(fctx, ISC_TRUE);       /* Locks bucket. */
3969                 return;
3970         }
3971
3972         isc_stdtime_get(&now);
3973
3974         if (negative) {
3975                 dns_rdatatype_t covers;
3976                 FCTXTRACE("nonexistence validation OK");
3977
3978                 inc_stats(fctx->res, dns_resstatscounter_valnegsuccess);
3979
3980                 if (fctx->rmessage->rcode == dns_rcode_nxdomain)
3981                         covers = dns_rdatatype_any;
3982                 else
3983                         covers = fctx->type;
3984
3985                 result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE,
3986                                          &node);
3987                 if (result != ISC_R_SUCCESS)
3988                         goto noanswer_response;
3989
3990                 /*
3991                  * If we are asking for a SOA record set the cache time
3992                  * to zero to facilitate locating the containing zone of
3993                  * a arbitrary zone.
3994                  */
3995                 ttl = fctx->res->view->maxncachettl;
3996                 if (fctx->type == dns_rdatatype_soa &&
3997                     covers == dns_rdatatype_any &&
3998                     fctx->res->zero_no_soa_ttl)
3999                         ttl = 0;
4000
4001                 result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
4002                                            covers, now, ttl, vevent->optout,
4003                                            ardataset, &eresult);
4004                 if (result != ISC_R_SUCCESS)
4005                         goto noanswer_response;
4006                 goto answer_response;
4007         } else
4008                 inc_stats(fctx->res, dns_resstatscounter_valsuccess);
4009
4010         FCTXTRACE("validation OK");
4011
4012         if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
4013
4014                 result = dns_rdataset_addnoqname(vevent->rdataset,
4015                                    vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]);
4016                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4017                 INSIST(vevent->sigrdataset != NULL);
4018                 vevent->sigrdataset->ttl = vevent->rdataset->ttl;
4019                 if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) {
4020                         result = dns_rdataset_addclosest(vevent->rdataset,
4021                                  vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]);
4022                         RUNTIME_CHECK(result == ISC_R_SUCCESS);
4023                 }
4024         }
4025
4026         /*
4027          * The data was already cached as pending data.
4028          * Re-cache it as secure and bind the cached
4029          * rdatasets to the first event on the fetch
4030          * event list.
4031          */
4032         result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node);
4033         if (result != ISC_R_SUCCESS)
4034                 goto noanswer_response;
4035
4036         result = dns_db_addrdataset(fctx->cache, node, NULL, now,
4037                                     vevent->rdataset, 0, ardataset);
4038         if (result != ISC_R_SUCCESS &&
4039             result != DNS_R_UNCHANGED)
4040                 goto noanswer_response;
4041         if (ardataset != NULL && ardataset->type == 0) {
4042                 if (NXDOMAIN(ardataset))
4043                         eresult = DNS_R_NCACHENXDOMAIN;
4044                 else
4045                         eresult = DNS_R_NCACHENXRRSET;
4046         } else if (vevent->sigrdataset != NULL) {
4047                 result = dns_db_addrdataset(fctx->cache, node, NULL, now,
4048                                             vevent->sigrdataset, 0,
4049                                             asigrdataset);
4050                 if (result != ISC_R_SUCCESS &&
4051                     result != DNS_R_UNCHANGED)
4052                         goto noanswer_response;
4053         }
4054
4055         if (sentresponse) {
4056                 /*
4057                  * If we only deferred the destroy because we wanted to cache
4058                  * the data, destroy now.
4059                  */
4060                 dns_db_detachnode(fctx->cache, &node);
4061                 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
4062                 if (SHUTTINGDOWN(fctx))
4063                         maybe_destroy(fctx);    /* Locks bucket. */
4064                 goto cleanup_event;
4065         }
4066
4067         if (!ISC_LIST_EMPTY(fctx->validators)) {
4068                 INSIST(!negative);
4069                 INSIST(fctx->type == dns_rdatatype_any ||
4070                        fctx->type == dns_rdatatype_rrsig ||
4071                        fctx->type == dns_rdatatype_sig);
4072                 /*
4073                  * Don't send a response yet - we have
4074                  * more rdatasets that still need to
4075                  * be validated.
4076                  */
4077                 dns_db_detachnode(fctx->cache, &node);
4078                 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
4079                 dns_validator_send(ISC_LIST_HEAD(fctx->validators));
4080                 goto cleanup_event;
4081         }
4082
4083  answer_response:
4084         /*
4085          * Cache any NS/NSEC records that happened to be validated.
4086          */
4087         result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
4088         while (result == ISC_R_SUCCESS) {
4089                 name = NULL;
4090                 dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY,
4091                                         &name);
4092                 for (rdataset = ISC_LIST_HEAD(name->list);
4093                      rdataset != NULL;
4094                      rdataset = ISC_LIST_NEXT(rdataset, link)) {
4095                         if ((rdataset->type != dns_rdatatype_ns &&
4096                              rdataset->type != dns_rdatatype_nsec) ||
4097                             rdataset->trust != dns_trust_secure)
4098                                 continue;
4099                         for (sigrdataset = ISC_LIST_HEAD(name->list);
4100                              sigrdataset != NULL;
4101                              sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
4102                                 if (sigrdataset->type != dns_rdatatype_rrsig ||
4103                                     sigrdataset->covers != rdataset->type)
4104                                         continue;
4105                                 break;
4106                         }
4107                         if (sigrdataset == NULL ||
4108                             sigrdataset->trust != dns_trust_secure)
4109                                 continue;
4110                         result = dns_db_findnode(fctx->cache, name, ISC_TRUE,
4111                                                  &nsnode);
4112                         if (result != ISC_R_SUCCESS)
4113                                 continue;
4114
4115                         result = dns_db_addrdataset(fctx->cache, nsnode, NULL,
4116                                                     now, rdataset, 0, NULL);
4117                         if (result == ISC_R_SUCCESS)
4118                                 result = dns_db_addrdataset(fctx->cache, nsnode,
4119                                                             NULL, now,
4120                                                             sigrdataset, 0,
4121                                                             NULL);
4122                         dns_db_detachnode(fctx->cache, &nsnode);
4123                 }
4124                 result = dns_message_nextname(fctx->rmessage,
4125                                               DNS_SECTION_AUTHORITY);
4126         }
4127
4128         result = ISC_R_SUCCESS;
4129
4130         /*
4131          * Respond with an answer, positive or negative,
4132          * as opposed to an error.  'node' must be non-NULL.
4133          */
4134
4135         fctx->attributes |= FCTX_ATTR_HAVEANSWER;
4136
4137         if (hevent != NULL) {
4138                 hevent->result = eresult;
4139                 RUNTIME_CHECK(dns_name_copy(vevent->name,
4140                               dns_fixedname_name(&hevent->foundname), NULL)
4141                               == ISC_R_SUCCESS);
4142                 dns_db_attach(fctx->cache, &hevent->db);
4143                 dns_db_transfernode(fctx->cache, &node, &hevent->node);
4144                 clone_results(fctx);
4145         }
4146
4147  noanswer_response:
4148         if (node != NULL)
4149                 dns_db_detachnode(fctx->cache, &node);
4150
4151         UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
4152
4153         fctx_done(fctx, result, __LINE__); /* Locks bucket. */
4154
4155  cleanup_event:
4156         INSIST(node == NULL);
4157         isc_event_free(&event);
4158 }
4159
4160 static inline isc_result_t
4161 cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
4162            isc_stdtime_t now)
4163 {
4164         dns_rdataset_t *rdataset, *sigrdataset;
4165         dns_rdataset_t *addedrdataset, *ardataset, *asigrdataset;
4166         dns_rdataset_t *valrdataset = NULL, *valsigrdataset = NULL;
4167         dns_dbnode_t *node, **anodep;
4168         dns_db_t **adbp;
4169         dns_name_t *aname;
4170         dns_resolver_t *res;
4171         isc_boolean_t need_validation, secure_domain, have_answer;
4172         isc_result_t result, eresult;
4173         dns_fetchevent_t *event;
4174         unsigned int options;
4175         isc_task_t *task;
4176         isc_boolean_t fail;
4177         unsigned int valoptions = 0;
4178
4179         /*
4180          * The appropriate bucket lock must be held.
4181          */
4182
4183         res = fctx->res;
4184         need_validation = ISC_FALSE;
4185         secure_domain = ISC_FALSE;
4186         have_answer = ISC_FALSE;
4187         eresult = ISC_R_SUCCESS;
4188         task = res->buckets[fctx->bucketnum].task;
4189
4190         /*
4191          * Is DNSSEC validation required for this name?
4192          */
4193         if (res->view->enablevalidation) {
4194                 result = dns_keytable_issecuredomain(res->view->secroots, name,
4195                                                      &secure_domain);
4196                 if (result != ISC_R_SUCCESS)
4197                         return (result);
4198
4199                 if (!secure_domain && res->view->dlv != NULL) {
4200                         valoptions = DNS_VALIDATOR_DLV;
4201                         secure_domain = ISC_TRUE;
4202                 }
4203         }
4204
4205         if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
4206                 need_validation = ISC_FALSE;
4207         else
4208                 need_validation = secure_domain;
4209
4210         adbp = NULL;
4211         aname = NULL;
4212         anodep = NULL;
4213         ardataset = NULL;
4214         asigrdataset = NULL;
4215         event = NULL;
4216         if ((name->attributes & DNS_NAMEATTR_ANSWER) != 0 &&
4217             !need_validation) {
4218                 have_answer = ISC_TRUE;
4219                 event = ISC_LIST_HEAD(fctx->events);
4220                 if (event != NULL) {
4221                         adbp = &event->db;
4222                         aname = dns_fixedname_name(&event->foundname);
4223                         result = dns_name_copy(name, aname, NULL);
4224                         if (result != ISC_R_SUCCESS)
4225                                 return (result);
4226                         anodep = &event->node;
4227                         /*
4228                          * If this is an ANY, SIG or RRSIG query, we're not
4229                          * going to return any rdatasets, unless we encountered
4230                          * a CNAME or DNAME as "the answer".  In this case,
4231                          * we're going to return DNS_R_CNAME or DNS_R_DNAME
4232                          * and we must set up the rdatasets.
4233                          */
4234                         if ((fctx->type != dns_rdatatype_any &&
4235                              fctx->type != dns_rdatatype_rrsig &&
4236                              fctx->type != dns_rdatatype_sig) ||
4237                             (name->attributes & DNS_NAMEATTR_CHAINING) != 0) {
4238                                 ardataset = event->rdataset;
4239                                 asigrdataset = event->sigrdataset;
4240                         }
4241                 }
4242         }
4243
4244         /*
4245          * Find or create the cache node.
4246          */
4247         node = NULL;
4248         result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node);
4249         if (result != ISC_R_SUCCESS)
4250                 return (result);
4251
4252         /*
4253          * Cache or validate each cacheable rdataset.
4254          */
4255         fail = ISC_TF((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0);
4256         for (rdataset = ISC_LIST_HEAD(name->list);
4257              rdataset != NULL;
4258              rdataset = ISC_LIST_NEXT(rdataset, link)) {
4259                 if (!CACHE(rdataset))
4260                         continue;
4261                 if (CHECKNAMES(rdataset)) {
4262                         char namebuf[DNS_NAME_FORMATSIZE];
4263                         char typebuf[DNS_RDATATYPE_FORMATSIZE];
4264                         char classbuf[DNS_RDATATYPE_FORMATSIZE];
4265
4266                         dns_name_format(name, namebuf, sizeof(namebuf));
4267                         dns_rdatatype_format(rdataset->type, typebuf,
4268                                              sizeof(typebuf));
4269                         dns_rdataclass_format(rdataset->rdclass, classbuf,
4270                                               sizeof(classbuf));
4271                         isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
4272                                       DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
4273                                       "check-names %s %s/%s/%s",
4274                                       fail ? "failure" : "warning",
4275                                       namebuf, typebuf, classbuf);
4276                         if (fail) {
4277                                 if (ANSWER(rdataset)) {
4278                                         dns_db_detachnode(fctx->cache, &node);
4279                                         return (DNS_R_BADNAME);
4280                                 }
4281                                 continue;
4282                         }
4283                 }
4284
4285                 /*
4286                  * Enforce the configure maximum cache TTL.
4287                  */
4288                 if (rdataset->ttl > res->view->maxcachettl)
4289                         rdataset->ttl = res->view->maxcachettl;
4290
4291                 /*
4292                  * If this rrset is in a secure domain, do DNSSEC validation
4293                  * for it, unless it is glue.
4294                  */
4295                 if (secure_domain && rdataset->trust != dns_trust_glue) {
4296                         /*
4297                          * RRSIGs are validated as part of validating the
4298                          * type they cover.
4299                          */
4300                         if (rdataset->type == dns_rdatatype_rrsig)
4301                                 continue;
4302                         /*
4303                          * Find the SIG for this rdataset, if we have it.
4304                          */
4305                         for (sigrdataset = ISC_LIST_HEAD(name->list);
4306                              sigrdataset != NULL;
4307                              sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
4308                                 if (sigrdataset->type == dns_rdatatype_rrsig &&
4309                                     sigrdataset->covers == rdataset->type)
4310                                         break;
4311                         }
4312                         if (sigrdataset == NULL) {
4313                                 if (!ANSWER(rdataset) && need_validation) {
4314                                         /*
4315                                          * Ignore non-answer rdatasets that
4316                                          * are missing signatures.
4317                                          */
4318                                         continue;
4319                                 }
4320                         }
4321
4322                         /*
4323                          * Normalize the rdataset and sigrdataset TTLs.
4324                          */
4325                         if (sigrdataset != NULL) {
4326                                 rdataset->ttl = ISC_MIN(rdataset->ttl,
4327                                                         sigrdataset->ttl);
4328                                 sigrdataset->ttl = rdataset->ttl;
4329                         }
4330
4331                         /*
4332                          * Cache this rdataset/sigrdataset pair as
4333                          * pending data.
4334                          */
4335                         rdataset->trust = dns_trust_pending;
4336                         if (sigrdataset != NULL)
4337                                 sigrdataset->trust = dns_trust_pending;
4338                         if (!need_validation || !ANSWER(rdataset)) {
4339                                 addedrdataset = ardataset;
4340                                 result = dns_db_addrdataset(fctx->cache, node,
4341                                                             NULL, now, rdataset,
4342                                                             0, addedrdataset);
4343                                 if (result == DNS_R_UNCHANGED) {
4344                                         result = ISC_R_SUCCESS;
4345                                         if (!need_validation &&
4346                                             ardataset != NULL &&
4347                                             ardataset->type == 0) {
4348                                                 /*
4349                                                  * The answer in the cache is
4350                                                  * better than the answer we
4351                                                  * found, and is a negative
4352                                                  * cache entry, so we must set
4353                                                  * eresult appropriately.
4354                                                  */
4355                                                 if (NXDOMAIN(ardataset))
4356                                                         eresult =
4357                                                            DNS_R_NCACHENXDOMAIN;
4358                                                 else
4359                                                         eresult =
4360                                                            DNS_R_NCACHENXRRSET;
4361                                                 /*
4362                                                  * We have a negative response
4363                                                  * from the cache so don't
4364                                                  * attempt to add the RRSIG
4365                                                  * rrset.
4366                                                  */
4367                                                 continue;
4368                                         }
4369                                 }
4370                                 if (result != ISC_R_SUCCESS)
4371                                         break;
4372                                 if (sigrdataset != NULL) {
4373                                         addedrdataset = asigrdataset;
4374                                         result = dns_db_addrdataset(fctx->cache,
4375                                                                 node, NULL, now,
4376                                                                 sigrdataset, 0,
4377                                                                 addedrdataset);
4378                                         if (result == DNS_R_UNCHANGED)
4379                                                 result = ISC_R_SUCCESS;
4380                                         if (result != ISC_R_SUCCESS)
4381                                                 break;
4382                                 } else if (!ANSWER(rdataset))
4383                                         continue;
4384                         }
4385
4386                         if (ANSWER(rdataset) && need_validation) {
4387                                 if (fctx->type != dns_rdatatype_any &&
4388                                     fctx->type != dns_rdatatype_rrsig &&
4389                                     fctx->type != dns_rdatatype_sig) {
4390                                         /*
4391                                          * This is The Answer.  We will
4392                                          * validate it, but first we cache
4393                                          * the rest of the response - it may
4394                                          * contain useful keys.
4395                                          */
4396                                         INSIST(valrdataset == NULL &&
4397                                                valsigrdataset == NULL);
4398                                         valrdataset = rdataset;
4399                                         valsigrdataset = sigrdataset;
4400                                 } else {
4401                                         /*
4402                                          * This is one of (potentially)
4403                                          * multiple answers to an ANY
4404                                          * or SIG query.  To keep things
4405                                          * simple, we just start the
4406                                          * validator right away rather
4407                                          * than caching first and
4408                                          * having to remember which
4409                                          * rdatasets needed validation.
4410                                          */
4411                                         result = valcreate(fctx, addrinfo,
4412                                                            name, rdataset->type,
4413                                                            rdataset,
4414                                                            sigrdataset,
4415                                                            valoptions, task);
4416                                         /*
4417                                          * Defer any further validations.
4418                                          * This prevents multiple validators
4419                                          * from manipulating fctx->rmessage
4420                                          * simultaneously.
4421                                          */
4422                                         valoptions |= DNS_VALIDATOR_DEFER;
4423                                 }
4424                         } else if (CHAINING(rdataset)) {
4425                                 if (rdataset->type == dns_rdatatype_cname)
4426                                         eresult = DNS_R_CNAME;
4427                                 else {
4428                                         INSIST(rdataset->type ==
4429                                                dns_rdatatype_dname);
4430                                         eresult = DNS_R_DNAME;
4431                                 }
4432                         }
4433                 } else if (!EXTERNAL(rdataset)) {
4434                         /*
4435                          * It's OK to cache this rdataset now.
4436                          */
4437                         if (ANSWER(rdataset))
4438                                 addedrdataset = ardataset;
4439                         else if (ANSWERSIG(rdataset))
4440                                 addedrdataset = asigrdataset;
4441                         else
4442                                 addedrdataset = NULL;
4443                         if (CHAINING(rdataset)) {
4444                                 if (rdataset->type == dns_rdatatype_cname)
4445                                         eresult = DNS_R_CNAME;
4446                                 else {
4447                                         INSIST(rdataset->type ==
4448                                                dns_rdatatype_dname);
4449                                         eresult = DNS_R_DNAME;
4450                                 }
4451                         }
4452                         if (rdataset->trust == dns_trust_glue &&
4453                             (rdataset->type == dns_rdatatype_ns ||
4454                              (rdataset->type == dns_rdatatype_rrsig &&
4455                               rdataset->covers == dns_rdatatype_ns))) {
4456                                 /*
4457                                  * If the trust level is 'dns_trust_glue'
4458                                  * then we are adding data from a referral
4459                                  * we got while executing the search algorithm.
4460                                  * New referral data always takes precedence
4461                                  * over the existing cache contents.
4462                                  */
4463                                 options = DNS_DBADD_FORCE;
4464                         } else
4465                                 options = 0;
4466                         /*
4467                          * Now we can add the rdataset.
4468                          */
4469                         result = dns_db_addrdataset(fctx->cache,
4470                                                     node, NULL, now,
4471                                                     rdataset,
4472                                                     options,
4473                                                     addedrdataset);
4474                         if (result == DNS_R_UNCHANGED) {
4475                                 if (ANSWER(rdataset) &&
4476                                     ardataset != NULL &&
4477                                     ardataset->type == 0) {
4478                                         /*
4479                                          * The answer in the cache is better
4480                                          * than the answer we found, and is
4481                                          * a negative cache entry, so we
4482                                          * must set eresult appropriately.
4483                                          */
4484                                         if (NXDOMAIN(ardataset))
4485                                                 eresult = DNS_R_NCACHENXDOMAIN;
4486                                         else
4487                                                 eresult = DNS_R_NCACHENXRRSET;
4488                                 }
4489                                 result = ISC_R_SUCCESS;
4490                         } else if (result != ISC_R_SUCCESS)
4491                                 break;
4492                 }
4493         }
4494
4495         if (valrdataset != NULL)
4496                 result = valcreate(fctx, addrinfo, name, fctx->type,
4497                                    valrdataset, valsigrdataset, valoptions,
4498                                    task);
4499
4500         if (result == ISC_R_SUCCESS && have_answer) {
4501                 fctx->attributes |= FCTX_ATTR_HAVEANSWER;
4502                 if (event != NULL) {
4503                         /*
4504                          * Negative results must be indicated in event->result.
4505                          */
4506                         if (dns_rdataset_isassociated(event->rdataset) &&
4507                             event->rdataset->type == dns_rdatatype_none) {
4508                                 INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
4509                                        eresult == DNS_R_NCACHENXRRSET);
4510                         }
4511                         event->result = eresult;
4512                         dns_db_attach(fctx->cache, adbp);
4513                         dns_db_transfernode(fctx->cache, &node, anodep);
4514                         clone_results(fctx);
4515                 }
4516         }
4517
4518         if (node != NULL)
4519                 dns_db_detachnode(fctx->cache, &node);
4520
4521         return (result);
4522 }
4523
4524 static inline isc_result_t
4525 cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
4526 {
4527         isc_result_t result;
4528         dns_section_t section;
4529         dns_name_t *name;
4530
4531         FCTXTRACE("cache_message");
4532
4533         fctx->attributes &= ~FCTX_ATTR_WANTCACHE;
4534
4535         LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
4536
4537         for (section = DNS_SECTION_ANSWER;
4538              section <= DNS_SECTION_ADDITIONAL;
4539              section++) {
4540                 result = dns_message_firstname(fctx->rmessage, section);
4541                 while (result == ISC_R_SUCCESS) {
4542                         name = NULL;
4543                         dns_message_currentname(fctx->rmessage, section,
4544                                                 &name);
4545                         if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) {
4546                                 result = cache_name(fctx, name, addrinfo, now);
4547                                 if (result != ISC_R_SUCCESS)
4548                                         break;
4549                         }
4550                         result = dns_message_nextname(fctx->rmessage, section);
4551                 }
4552                 if (result != ISC_R_NOMORE)
4553                         break;
4554         }
4555         if (result == ISC_R_NOMORE)
4556                 result = ISC_R_SUCCESS;
4557
4558         UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
4559
4560         return (result);
4561 }
4562
4563 /*
4564  * Do what dns_ncache_addoptout() does, and then compute an appropriate eresult.
4565  */
4566 static isc_result_t
4567 ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
4568                   dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
4569                   isc_boolean_t optout, dns_rdataset_t *ardataset,
4570                   isc_result_t *eresultp)
4571 {
4572         isc_result_t result;
4573         dns_rdataset_t rdataset;
4574
4575         if (ardataset == NULL) {
4576                 dns_rdataset_init(&rdataset);
4577                 ardataset = &rdataset;
4578         }
4579         result = dns_ncache_addoptout(message, cache, node, covers, now,
4580                                      maxttl, optout, ardataset);
4581         if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) {
4582                 /*
4583                  * If the cache now contains a negative entry and we
4584                  * care about whether it is DNS_R_NCACHENXDOMAIN or
4585                  * DNS_R_NCACHENXRRSET then extract it.
4586                  */
4587                 if (ardataset->type == 0) {
4588                         /*
4589                          * The cache data is a negative cache entry.
4590                          */
4591                         if (NXDOMAIN(ardataset))
4592                                 *eresultp = DNS_R_NCACHENXDOMAIN;
4593                         else
4594                                 *eresultp = DNS_R_NCACHENXRRSET;
4595                 } else {
4596                         /*
4597                          * Either we don't care about the nature of the
4598                          * cache rdataset (because no fetch is interested
4599                          * in the outcome), or the cache rdataset is not
4600                          * a negative cache entry.  Whichever case it is,
4601                          * we can return success.
4602                          *
4603                          * XXXRTH  There's a CNAME/DNAME problem here.
4604                          */
4605                         *eresultp = ISC_R_SUCCESS;
4606                 }
4607                 result = ISC_R_SUCCESS;
4608         }
4609         if (ardataset == &rdataset && dns_rdataset_isassociated(ardataset))
4610                 dns_rdataset_disassociate(ardataset);
4611
4612         return (result);
4613 }
4614
4615 static inline isc_result_t
4616 ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
4617                dns_rdatatype_t covers, isc_stdtime_t now)
4618 {
4619         isc_result_t result, eresult;
4620         dns_name_t *name;
4621         dns_resolver_t *res;
4622         dns_db_t **adbp;
4623         dns_dbnode_t *node, **anodep;
4624         dns_rdataset_t *ardataset;
4625         isc_boolean_t need_validation, secure_domain;
4626         dns_name_t *aname;
4627         dns_fetchevent_t *event;
4628         isc_uint32_t ttl;
4629         unsigned int valoptions = 0;
4630
4631         FCTXTRACE("ncache_message");
4632
4633         fctx->attributes &= ~FCTX_ATTR_WANTNCACHE;
4634
4635         res = fctx->res;
4636         need_validation = ISC_FALSE;
4637         secure_domain = ISC_FALSE;
4638         eresult = ISC_R_SUCCESS;
4639         name = &fctx->name;
4640         node = NULL;
4641
4642         /*
4643          * XXXMPA remove when we follow cnames and adjust the setting
4644          * of FCTX_ATTR_WANTNCACHE in noanswer_response().
4645          */
4646         INSIST(fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0);
4647
4648         /*
4649          * Is DNSSEC validation required for this name?
4650          */
4651         if (fctx->res->view->enablevalidation) {
4652                 result = dns_keytable_issecuredomain(res->view->secroots, name,
4653                                                      &secure_domain);
4654                 if (result != ISC_R_SUCCESS)
4655                         return (result);
4656
4657                 if (!secure_domain && res->view->dlv != NULL) {
4658                         valoptions = DNS_VALIDATOR_DLV;
4659                         secure_domain = ISC_TRUE;
4660                 }
4661         }
4662
4663         if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
4664                 need_validation = ISC_FALSE;
4665         else
4666                 need_validation = secure_domain;
4667
4668         if (secure_domain) {
4669                 /*
4670                  * Mark all rdatasets as pending.
4671                  */
4672                 dns_rdataset_t *trdataset;
4673                 dns_name_t *tname;
4674
4675                 result = dns_message_firstname(fctx->rmessage,
4676                                                DNS_SECTION_AUTHORITY);
4677                 while (result == ISC_R_SUCCESS) {
4678                         tname = NULL;
4679                         dns_message_currentname(fctx->rmessage,
4680                                                 DNS_SECTION_AUTHORITY,
4681                                                 &tname);
4682                         for (trdataset = ISC_LIST_HEAD(tname->list);
4683                              trdataset != NULL;
4684                              trdataset = ISC_LIST_NEXT(trdataset, link))
4685                                 trdataset->trust = dns_trust_pending;
4686                         result = dns_message_nextname(fctx->rmessage,
4687                                                       DNS_SECTION_AUTHORITY);
4688                 }
4689                 if (result != ISC_R_NOMORE)
4690                         return (result);
4691
4692         }
4693
4694         if (need_validation) {
4695                 /*
4696                  * Do negative response validation.
4697                  */
4698                 result = valcreate(fctx, addrinfo, name, fctx->type,
4699                                    NULL, NULL, valoptions,
4700                                    res->buckets[fctx->bucketnum].task);
4701                 /*
4702                  * If validation is necessary, return now.  Otherwise continue
4703                  * to process the message, letting the validation complete
4704                  * in its own good time.
4705                  */
4706                 return (result);
4707         }
4708
4709         LOCK(&res->buckets[fctx->bucketnum].lock);
4710
4711         adbp = NULL;
4712         aname = NULL;
4713         anodep = NULL;
4714         ardataset = NULL;
4715         if (!HAVE_ANSWER(fctx)) {
4716                 event = ISC_LIST_HEAD(fctx->events);
4717                 if (event != NULL) {
4718                         adbp = &event->db;
4719                         aname = dns_fixedname_name(&event->foundname);
4720                         result = dns_name_copy(name, aname, NULL);
4721                         if (result != ISC_R_SUCCESS)
4722                                 goto unlock;
4723                         anodep = &event->node;
4724                         ardataset = event->rdataset;
4725                 }
4726         } else
4727                 event = NULL;
4728
4729         result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node);
4730         if (result != ISC_R_SUCCESS)
4731                 goto unlock;
4732
4733         /*
4734          * If we are asking for a SOA record set the cache time
4735          * to zero to facilitate locating the containing zone of
4736          * a arbitrary zone.
4737          */
4738         ttl = fctx->res->view->maxncachettl;
4739         if (fctx->type == dns_rdatatype_soa &&
4740             covers == dns_rdatatype_any &&
4741             fctx->res->zero_no_soa_ttl)
4742                 ttl = 0;
4743
4744         result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
4745                                    covers, now, ttl, ISC_FALSE,
4746                                    ardataset, &eresult);
4747         if (result != ISC_R_SUCCESS)
4748                 goto unlock;
4749
4750         if (!HAVE_ANSWER(fctx)) {
4751                 fctx->attributes |= FCTX_ATTR_HAVEANSWER;
4752                 if (event != NULL) {
4753                         event->result = eresult;
4754                         dns_db_attach(fctx->cache, adbp);
4755                         dns_db_transfernode(fctx->cache, &node, anodep);
4756                         clone_results(fctx);
4757                 }
4758         }
4759
4760  unlock:
4761         UNLOCK(&res->buckets[fctx->bucketnum].lock);
4762
4763         if (node != NULL)
4764                 dns_db_detachnode(fctx->cache, &node);
4765
4766         return (result);
4767 }
4768
4769 static inline void
4770 mark_related(dns_name_t *name, dns_rdataset_t *rdataset,
4771              isc_boolean_t external, isc_boolean_t gluing)
4772 {
4773         name->attributes |= DNS_NAMEATTR_CACHE;
4774         if (gluing) {
4775                 rdataset->trust = dns_trust_glue;
4776                 /*
4777                  * Glue with 0 TTL causes problems.  We force the TTL to
4778                  * 1 second to prevent this.
4779                  */
4780                 if (rdataset->ttl == 0)
4781                         rdataset->ttl = 1;
4782         } else
4783                 rdataset->trust = dns_trust_additional;
4784         /*
4785          * Avoid infinite loops by only marking new rdatasets.
4786          */
4787         if (!CACHE(rdataset)) {
4788                 name->attributes |= DNS_NAMEATTR_CHASE;
4789                 rdataset->attributes |= DNS_RDATASETATTR_CHASE;
4790         }
4791         rdataset->attributes |= DNS_RDATASETATTR_CACHE;
4792         if (external)
4793                 rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL;
4794 }
4795
4796 static isc_result_t
4797 check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
4798         fetchctx_t *fctx = arg;
4799         isc_result_t result;
4800         dns_name_t *name;
4801         dns_rdataset_t *rdataset;
4802         isc_boolean_t external;
4803         dns_rdatatype_t rtype;
4804         isc_boolean_t gluing;
4805
4806         REQUIRE(VALID_FCTX(fctx));
4807
4808         if (GLUING(fctx))
4809                 gluing = ISC_TRUE;
4810         else
4811                 gluing = ISC_FALSE;
4812         name = NULL;
4813         rdataset = NULL;
4814         result = dns_message_findname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
4815                                       addname, dns_rdatatype_any, 0, &name,
4816                                       NULL);
4817         if (result == ISC_R_SUCCESS) {
4818                 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
4819                 if (type == dns_rdatatype_a) {
4820                         for (rdataset = ISC_LIST_HEAD(name->list);
4821                              rdataset != NULL;
4822                              rdataset = ISC_LIST_NEXT(rdataset, link)) {
4823                                 if (rdataset->type == dns_rdatatype_rrsig)
4824                                         rtype = rdataset->covers;
4825                                 else
4826                                         rtype = rdataset->type;
4827                                 if (rtype == dns_rdatatype_a ||
4828                                     rtype == dns_rdatatype_aaaa)
4829                                         mark_related(name, rdataset, external,
4830                                                      gluing);
4831                         }
4832                 } else {
4833                         result = dns_message_findtype(name, type, 0,
4834                                                       &rdataset);
4835                         if (result == ISC_R_SUCCESS) {
4836                                 mark_related(name, rdataset, external, gluing);
4837                                 /*
4838                                  * Do we have its SIG too?
4839                                  */
4840                                 rdataset = NULL;
4841                                 result = dns_message_findtype(name,
4842                                                       dns_rdatatype_rrsig,
4843                                                       type, &rdataset);
4844                                 if (result == ISC_R_SUCCESS)
4845                                         mark_related(name, rdataset, external,
4846                                                      gluing);
4847                         }
4848                 }
4849         }
4850
4851         return (ISC_R_SUCCESS);
4852 }
4853
4854 static void
4855 chase_additional(fetchctx_t *fctx) {
4856         isc_boolean_t rescan;
4857         dns_section_t section = DNS_SECTION_ADDITIONAL;
4858         isc_result_t result;
4859
4860  again:
4861         rescan = ISC_FALSE;
4862
4863         for (result = dns_message_firstname(fctx->rmessage, section);
4864              result == ISC_R_SUCCESS;
4865              result = dns_message_nextname(fctx->rmessage, section)) {
4866                 dns_name_t *name = NULL;
4867                 dns_rdataset_t *rdataset;
4868                 dns_message_currentname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
4869                                         &name);
4870                 if ((name->attributes & DNS_NAMEATTR_CHASE) == 0)
4871                         continue;
4872                 name->attributes &= ~DNS_NAMEATTR_CHASE;
4873                 for (rdataset = ISC_LIST_HEAD(name->list);
4874                      rdataset != NULL;
4875                      rdataset = ISC_LIST_NEXT(rdataset, link)) {
4876                         if (CHASE(rdataset)) {
4877                                 rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
4878                                 (void)dns_rdataset_additionaldata(rdataset,
4879                                                                   check_related,
4880                                                                   fctx);
4881                                 rescan = ISC_TRUE;
4882                         }
4883                 }
4884         }
4885         if (rescan)
4886                 goto again;
4887 }
4888
4889 static inline isc_result_t
4890 cname_target(dns_rdataset_t *rdataset, dns_name_t *tname) {
4891         isc_result_t result;
4892         dns_rdata_t rdata = DNS_RDATA_INIT;
4893         dns_rdata_cname_t cname;
4894
4895         result = dns_rdataset_first(rdataset);
4896         if (result != ISC_R_SUCCESS)
4897                 return (result);
4898         dns_rdataset_current(rdataset, &rdata);
4899         result = dns_rdata_tostruct(&rdata, &cname, NULL);
4900         if (result != ISC_R_SUCCESS)
4901                 return (result);
4902         dns_name_init(tname, NULL);
4903         dns_name_clone(&cname.cname, tname);
4904         dns_rdata_freestruct(&cname);
4905
4906         return (ISC_R_SUCCESS);
4907 }
4908
4909 static inline isc_result_t
4910 dname_target(dns_rdataset_t *rdataset, dns_name_t *qname, dns_name_t *oname,
4911              dns_fixedname_t *fixeddname)
4912 {
4913         isc_result_t result;
4914         dns_rdata_t rdata = DNS_RDATA_INIT;
4915         unsigned int nlabels;
4916         int order;
4917         dns_namereln_t namereln;
4918         dns_rdata_dname_t dname;
4919         dns_fixedname_t prefix;
4920
4921         /*
4922          * Get the target name of the DNAME.
4923          */
4924
4925         result = dns_rdataset_first(rdataset);
4926         if (result != ISC_R_SUCCESS)
4927                 return (result);
4928         dns_rdataset_current(rdataset, &rdata);
4929         result = dns_rdata_tostruct(&rdata, &dname, NULL);
4930         if (result != ISC_R_SUCCESS)
4931                 return (result);
4932
4933         /*
4934          * Get the prefix of qname.
4935          */
4936         namereln = dns_name_fullcompare(qname, oname, &order, &nlabels);
4937         if (namereln != dns_namereln_subdomain) {
4938                 dns_rdata_freestruct(&dname);
4939                 return (DNS_R_FORMERR);
4940         }
4941         dns_fixedname_init(&prefix);
4942         dns_name_split(qname, nlabels, dns_fixedname_name(&prefix), NULL);
4943         dns_fixedname_init(fixeddname);
4944         result = dns_name_concatenate(dns_fixedname_name(&prefix),
4945                                       &dname.dname,
4946                                       dns_fixedname_name(fixeddname), NULL);
4947         dns_rdata_freestruct(&dname);
4948         return (result);
4949 }
4950
4951 /*
4952  * Handle a no-answer response (NXDOMAIN, NXRRSET, or referral).
4953  * If bind8_ns_resp is ISC_TRUE, this is a suspected BIND 8
4954  * response to an NS query that should be treated as a referral
4955  * even though the NS records occur in the answer section
4956  * rather than the authority section.
4957  */
4958 static isc_result_t
4959 noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
4960                   isc_boolean_t bind8_ns_resp)
4961 {
4962         isc_result_t result;
4963         dns_message_t *message;
4964         dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name;
4965         dns_rdataset_t *rdataset, *ns_rdataset;
4966         isc_boolean_t aa, negative_response;
4967         dns_rdatatype_t type;
4968         dns_section_t section =
4969                 bind8_ns_resp ? DNS_SECTION_ANSWER : DNS_SECTION_AUTHORITY;
4970
4971         FCTXTRACE("noanswer_response");
4972
4973         message = fctx->rmessage;
4974
4975         /*
4976          * Setup qname.
4977          */
4978         if (oqname == NULL) {
4979                 /*
4980                  * We have a normal, non-chained negative response or
4981                  * referral.
4982                  */
4983                 if ((message->flags & DNS_MESSAGEFLAG_AA) != 0)
4984                         aa = ISC_TRUE;
4985                 else
4986                         aa = ISC_FALSE;
4987                 qname = &fctx->name;
4988         } else {
4989                 /*
4990                  * We're being invoked by answer_response() after it has
4991                  * followed a CNAME/DNAME chain.
4992                  */
4993                 qname = oqname;
4994                 aa = ISC_FALSE;
4995                 /*
4996                  * If the current qname is not a subdomain of the query
4997                  * domain, there's no point in looking at the authority
4998                  * section without doing DNSSEC validation.
4999                  *
5000                  * Until we do that validation, we'll just return success
5001                  * in this case.
5002                  */
5003                 if (!dns_name_issubdomain(qname, &fctx->domain))
5004                         return (ISC_R_SUCCESS);
5005         }
5006
5007         /*
5008          * We have to figure out if this is a negative response, or a
5009          * referral.
5010          */
5011
5012         /*
5013          * Sometimes we can tell if its a negative response by looking at
5014          * the message header.
5015          */
5016         negative_response = ISC_FALSE;
5017         if (message->rcode == dns_rcode_nxdomain ||
5018             (message->counts[DNS_SECTION_ANSWER] == 0 &&
5019              message->counts[DNS_SECTION_AUTHORITY] == 0))
5020                 negative_response = ISC_TRUE;
5021
5022         /*
5023          * Process the authority section.
5024          */
5025         ns_name = NULL;
5026         ns_rdataset = NULL;
5027         soa_name = NULL;
5028         ds_name = NULL;
5029         result = dns_message_firstname(message, section);
5030         while (result == ISC_R_SUCCESS) {
5031                 name = NULL;
5032                 dns_message_currentname(message, section, &name);
5033                 if (dns_name_issubdomain(name, &fctx->domain)) {
5034                         /*
5035                          * Look for NS/SOA RRsets first.
5036                          */
5037                         for (rdataset = ISC_LIST_HEAD(name->list);
5038                              rdataset != NULL;
5039                              rdataset = ISC_LIST_NEXT(rdataset, link)) {
5040                                 type = rdataset->type;
5041                                 if (type == dns_rdatatype_rrsig)
5042                                         type = rdataset->covers;
5043                                 if (((type == dns_rdatatype_ns ||
5044                                       type == dns_rdatatype_soa) &&
5045                                      !dns_name_issubdomain(qname, name)))
5046                                         return (DNS_R_FORMERR);
5047                                 if (type == dns_rdatatype_ns) {
5048                                         /*
5049                                          * NS or RRSIG NS.
5050                                          *
5051                                          * Only one set of NS RRs is allowed.
5052                                          */
5053                                         if (rdataset->type ==
5054                                             dns_rdatatype_ns) {
5055                                                 if (ns_name != NULL &&
5056                                                     name != ns_name)
5057                                                         return (DNS_R_FORMERR);
5058                                                 ns_name = name;
5059                                                 ns_rdataset = rdataset;
5060                                         }
5061                                         name->attributes |=
5062                                                 DNS_NAMEATTR_CACHE;
5063                                         rdataset->attributes |=
5064                                                 DNS_RDATASETATTR_CACHE;
5065                                         rdataset->trust = dns_trust_glue;
5066                                 }
5067                                 if (type == dns_rdatatype_soa) {
5068                                         /*
5069                                          * SOA, or RRSIG SOA.
5070                                          *
5071                                          * Only one SOA is allowed.
5072                                          */
5073                                         if (rdataset->type ==
5074                                             dns_rdatatype_soa) {
5075                                                 if (soa_name != NULL &&
5076                                                     name != soa_name)
5077                                                         return (DNS_R_FORMERR);
5078                                                 soa_name = name;
5079                                         }
5080                                         name->attributes |=
5081                                                 DNS_NAMEATTR_NCACHE;
5082                                         rdataset->attributes |=
5083                                                 DNS_RDATASETATTR_NCACHE;
5084                                         if (aa)
5085                                                 rdataset->trust =
5086                                                     dns_trust_authauthority;
5087                                         else
5088                                                 rdataset->trust =
5089                                                         dns_trust_additional;
5090                                 }
5091                         }
5092                 }
5093                 result = dns_message_nextname(message, section);
5094                 if (result == ISC_R_NOMORE)
5095                         break;
5096                 else if (result != ISC_R_SUCCESS)
5097                         return (result);
5098         }
5099
5100         /*
5101          * A negative response has a SOA record (Type 2)
5102          * and a optional NS RRset (Type 1) or it has neither
5103          * a SOA or a NS RRset (Type 3, handled above) or
5104          * rcode is NXDOMAIN (handled above) in which case
5105          * the NS RRset is allowed (Type 4).
5106          */
5107         if (soa_name != NULL)
5108                 negative_response = ISC_TRUE;
5109
5110         result = dns_message_firstname(message, section);
5111         while (result == ISC_R_SUCCESS) {
5112                 name = NULL;
5113                 dns_message_currentname(message, section, &name);
5114                 if (dns_name_issubdomain(name, &fctx->domain)) {
5115                         for (rdataset = ISC_LIST_HEAD(name->list);
5116                              rdataset != NULL;
5117                              rdataset = ISC_LIST_NEXT(rdataset, link)) {
5118                                 type = rdataset->type;
5119                                 if (type == dns_rdatatype_rrsig)
5120                                         type = rdataset->covers;
5121                                 if (type == dns_rdatatype_nsec ||
5122                                     type == dns_rdatatype_nsec3) {
5123                                         /*
5124                                          * NSEC or RRSIG NSEC.
5125                                          */
5126                                         if (negative_response) {
5127                                                 name->attributes |=
5128                                                         DNS_NAMEATTR_NCACHE;
5129                                                 rdataset->attributes |=
5130                                                         DNS_RDATASETATTR_NCACHE;
5131                                         } else if (type == dns_rdatatype_nsec) {
5132                                                 name->attributes |=
5133                                                         DNS_NAMEATTR_CACHE;
5134                                                 rdataset->attributes |=
5135                                                         DNS_RDATASETATTR_CACHE;
5136                                         }
5137                                         if (aa)
5138                                                 rdataset->trust =
5139                                                     dns_trust_authauthority;
5140                                         else
5141                                                 rdataset->trust =
5142                                                         dns_trust_additional;
5143                                         /*
5144                                          * No additional data needs to be
5145                                          * marked.
5146                                          */
5147                                 } else if (type == dns_rdatatype_ds) {
5148                                         /*
5149                                          * DS or SIG DS.
5150                                          *
5151                                          * These should only be here if
5152                                          * this is a referral, and there
5153                                          * should only be one DS.
5154                                          */
5155                                         if (ns_name == NULL)
5156                                                 return (DNS_R_FORMERR);
5157                                         if (rdataset->type ==
5158                                             dns_rdatatype_ds) {
5159                                                 if (ds_name != NULL &&
5160                                                     name != ds_name)
5161                                                         return (DNS_R_FORMERR);
5162                                                 ds_name = name;
5163                                         }
5164                                         name->attributes |=
5165                                                 DNS_NAMEATTR_CACHE;
5166                                         rdataset->attributes |=
5167                                                 DNS_RDATASETATTR_CACHE;
5168                                         if (aa)
5169                                                 rdataset->trust =
5170                                                     dns_trust_authauthority;
5171                                         else
5172                                                 rdataset->trust =
5173                                                         dns_trust_additional;
5174                                 }
5175                         }
5176                 }
5177                 result = dns_message_nextname(message, section);
5178                 if (result == ISC_R_NOMORE)
5179                         break;
5180                 else if (result != ISC_R_SUCCESS)
5181                         return (result);
5182         }
5183
5184         /*
5185          * Trigger lookups for DNS nameservers.
5186          */
5187         if (negative_response && message->rcode == dns_rcode_noerror &&
5188             fctx->type == dns_rdatatype_ds && soa_name != NULL &&
5189             dns_name_equal(soa_name, qname) &&
5190             !dns_name_equal(qname, dns_rootname))
5191                 return (DNS_R_CHASEDSSERVERS);
5192
5193         /*
5194          * Did we find anything?
5195          */
5196         if (!negative_response && ns_name == NULL) {
5197                 /*
5198                  * Nope.
5199                  */
5200                 if (oqname != NULL) {
5201                         /*
5202                          * We've already got a partial CNAME/DNAME chain,
5203                          * and haven't found else anything useful here, but
5204                          * no error has occurred since we have an answer.
5205                          */
5206                         return (ISC_R_SUCCESS);
5207                 } else {
5208                         /*
5209                          * The responder is insane.
5210                          */
5211                         return (DNS_R_FORMERR);
5212                 }
5213         }
5214
5215         /*
5216          * If we found both NS and SOA, they should be the same name.
5217          */
5218         if (ns_name != NULL && soa_name != NULL && ns_name != soa_name)
5219                 return (DNS_R_FORMERR);
5220
5221         /*
5222          * Do we have a referral?  (We only want to follow a referral if
5223          * we're not following a chain.)
5224          */
5225         if (!negative_response && ns_name != NULL && oqname == NULL) {
5226                 /*
5227                  * We already know ns_name is a subdomain of fctx->domain.
5228                  * If ns_name is equal to fctx->domain, we're not making
5229                  * progress.  We return DNS_R_FORMERR so that we'll keep
5230                  * trying other servers.
5231                  */
5232                 if (dns_name_equal(ns_name, &fctx->domain))
5233                         return (DNS_R_FORMERR);
5234
5235                 /*
5236                  * If the referral name is not a parent of the query
5237                  * name, consider the responder insane.
5238                  */
5239                 if (! dns_name_issubdomain(&fctx->name, ns_name)) {
5240                         FCTXTRACE("referral to non-parent");
5241                         return (DNS_R_FORMERR);
5242                 }
5243
5244                 /*
5245                  * Mark any additional data related to this rdataset.
5246                  * It's important that we do this before we change the
5247                  * query domain.
5248                  */
5249                 INSIST(ns_rdataset != NULL);
5250                 fctx->attributes |= FCTX_ATTR_GLUING;
5251                 (void)dns_rdataset_additionaldata(ns_rdataset, check_related,
5252                                                   fctx);
5253                 fctx->attributes &= ~FCTX_ATTR_GLUING;
5254                 /*
5255                  * NS rdatasets with 0 TTL cause problems.
5256                  * dns_view_findzonecut() will not find them when we
5257                  * try to follow the referral, and we'll SERVFAIL
5258                  * because the best nameservers are now above QDOMAIN.
5259                  * We force the TTL to 1 second to prevent this.
5260                  */
5261                 if (ns_rdataset->ttl == 0)
5262                         ns_rdataset->ttl = 1;
5263                 /*
5264                  * Set the current query domain to the referral name.
5265                  *
5266                  * XXXRTH  We should check if we're in forward-only mode, and
5267                  *              if so we should bail out.
5268                  */
5269                 INSIST(dns_name_countlabels(&fctx->domain) > 0);
5270                 dns_name_free(&fctx->domain,
5271                               fctx->res->buckets[fctx->bucketnum].mctx);
5272                 if (dns_rdataset_isassociated(&fctx->nameservers))
5273                         dns_rdataset_disassociate(&fctx->nameservers);
5274                 dns_name_init(&fctx->domain, NULL);
5275                 result = dns_name_dup(ns_name,
5276                                       fctx->res->buckets[fctx->bucketnum].mctx,
5277                                       &fctx->domain);
5278                 if (result != ISC_R_SUCCESS)
5279                         return (result);
5280                 fctx->attributes |= FCTX_ATTR_WANTCACHE;
5281                 return (DNS_R_DELEGATION);
5282         }
5283
5284         /*
5285          * Since we're not doing a referral, we don't want to cache any
5286          * NS RRs we may have found.
5287          */
5288         if (ns_name != NULL)
5289                 ns_name->attributes &= ~DNS_NAMEATTR_CACHE;
5290
5291         if (negative_response && oqname == NULL)
5292                 fctx->attributes |= FCTX_ATTR_WANTNCACHE;
5293
5294         return (ISC_R_SUCCESS);
5295 }
5296
5297 static isc_result_t
5298 answer_response(fetchctx_t *fctx) {
5299         isc_result_t result;
5300         dns_message_t *message;
5301         dns_name_t *name, *qname, tname;
5302         dns_rdataset_t *rdataset;
5303         isc_boolean_t done, external, chaining, aa, found, want_chaining;
5304         isc_boolean_t have_answer, found_cname, found_type, wanted_chaining;
5305         unsigned int aflag;
5306         dns_rdatatype_t type;
5307         dns_fixedname_t dname, fqname;
5308
5309         FCTXTRACE("answer_response");
5310
5311         message = fctx->rmessage;
5312
5313         /*
5314          * Examine the answer section, marking those rdatasets which are
5315          * part of the answer and should be cached.
5316          */
5317
5318         done = ISC_FALSE;
5319         found_cname = ISC_FALSE;
5320         found_type = ISC_FALSE;
5321         chaining = ISC_FALSE;
5322         have_answer = ISC_FALSE;
5323         want_chaining = ISC_FALSE;
5324         if ((message->flags & DNS_MESSAGEFLAG_AA) != 0)
5325                 aa = ISC_TRUE;
5326         else
5327                 aa = ISC_FALSE;
5328         qname = &fctx->name;
5329         type = fctx->type;
5330         result = dns_message_firstname(message, DNS_SECTION_ANSWER);
5331         while (!done && result == ISC_R_SUCCESS) {
5332                 name = NULL;
5333                 dns_message_currentname(message, DNS_SECTION_ANSWER, &name);
5334                 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
5335                 if (dns_name_equal(name, qname)) {
5336                         wanted_chaining = ISC_FALSE;
5337                         for (rdataset = ISC_LIST_HEAD(name->list);
5338                              rdataset != NULL;
5339                              rdataset = ISC_LIST_NEXT(rdataset, link)) {
5340                                 found = ISC_FALSE;
5341                                 want_chaining = ISC_FALSE;
5342                                 aflag = 0;
5343                                 if (rdataset->type == dns_rdatatype_nsec3) {
5344                                         /*
5345                                          * NSEC3 records are not allowed to
5346                                          * appear in the answer section.
5347                                          */
5348                                         return (DNS_R_FORMERR);
5349                                 }
5350                                 if (rdataset->type == type && !found_cname) {
5351                                         /*
5352                                          * We've found an ordinary answer.
5353                                          */
5354                                         found = ISC_TRUE;
5355                                         found_type = ISC_TRUE;
5356                                         done = ISC_TRUE;
5357                                         aflag = DNS_RDATASETATTR_ANSWER;
5358                                 } else if (type == dns_rdatatype_any) {
5359                                         /*
5360                                          * We've found an answer matching
5361                                          * an ANY query.  There may be
5362                                          * more.
5363                                          */
5364                                         found = ISC_TRUE;
5365                                         aflag = DNS_RDATASETATTR_ANSWER;
5366                                 } else if (rdataset->type == dns_rdatatype_rrsig
5367                                            && rdataset->covers == type
5368                                            && !found_cname) {
5369                                         /*
5370                                          * We've found a signature that
5371                                          * covers the type we're looking for.
5372                                          */
5373                                         found = ISC_TRUE;
5374                                         found_type = ISC_TRUE;
5375                                         aflag = DNS_RDATASETATTR_ANSWERSIG;
5376                                 } else if (rdataset->type ==
5377                                            dns_rdatatype_cname
5378                                            && !found_type) {
5379                                         /*
5380                                          * We're looking for something else,
5381                                          * but we found a CNAME.
5382                                          *
5383                                          * Getting a CNAME response for some
5384                                          * query types is an error.
5385                                          */
5386                                         if (type == dns_rdatatype_rrsig ||
5387                                             type == dns_rdatatype_dnskey ||
5388                                             type == dns_rdatatype_nsec)
5389                                                 return (DNS_R_FORMERR);
5390                                         found = ISC_TRUE;
5391                                         found_cname = ISC_TRUE;
5392                                         want_chaining = ISC_TRUE;
5393                                         aflag = DNS_RDATASETATTR_ANSWER;
5394                                         result = cname_target(rdataset,
5395                                                               &tname);
5396                                         if (result != ISC_R_SUCCESS)
5397                                                 return (result);
5398                                 } else if (rdataset->type == dns_rdatatype_rrsig
5399                                            && rdataset->covers ==
5400                                            dns_rdatatype_cname
5401                                            && !found_type) {
5402                                         /*
5403                                          * We're looking for something else,
5404                                          * but we found a SIG CNAME.
5405                                          */
5406                                         found = ISC_TRUE;
5407                                         found_cname = ISC_TRUE;
5408                                         aflag = DNS_RDATASETATTR_ANSWERSIG;
5409                                 }
5410
5411                                 if (found) {
5412                                         /*
5413                                          * We've found an answer to our
5414                                          * question.
5415                                          */
5416                                         name->attributes |=
5417                                                 DNS_NAMEATTR_CACHE;
5418                                         rdataset->attributes |=
5419                                                 DNS_RDATASETATTR_CACHE;
5420                                         rdataset->trust = dns_trust_answer;
5421                                         if (!chaining) {
5422                                                 /*
5423                                                  * This data is "the" answer
5424                                                  * to our question only if
5425                                                  * we're not chaining (i.e.
5426                                                  * if we haven't followed
5427                                                  * a CNAME or DNAME).
5428                                                  */
5429                                                 INSIST(!external);
5430                                                 if (aflag ==
5431                                                     DNS_RDATASETATTR_ANSWER)
5432                                                         have_answer = ISC_TRUE;
5433                                                 name->attributes |=
5434                                                         DNS_NAMEATTR_ANSWER;
5435                                                 rdataset->attributes |= aflag;
5436                                                 if (aa)
5437                                                         rdataset->trust =
5438                                                           dns_trust_authanswer;
5439                                         } else if (external) {
5440                                                 /*
5441                                                  * This data is outside of
5442                                                  * our query domain, and
5443                                                  * may only be cached if it
5444                                                  * comes from a secure zone
5445                                                  * and validates.
5446                                                  */
5447                                                 rdataset->attributes |=
5448                                                     DNS_RDATASETATTR_EXTERNAL;
5449                                         }
5450
5451                                         /*
5452                                          * Mark any additional data related
5453                                          * to this rdataset.
5454                                          */
5455                                         (void)dns_rdataset_additionaldata(
5456                                                         rdataset,
5457                                                         check_related,
5458                                                         fctx);
5459
5460                                         /*
5461                                          * CNAME chaining.
5462                                          */
5463                                         if (want_chaining) {
5464                                                 wanted_chaining = ISC_TRUE;
5465                                                 name->attributes |=
5466                                                         DNS_NAMEATTR_CHAINING;
5467                                                 rdataset->attributes |=
5468                                                     DNS_RDATASETATTR_CHAINING;
5469                                                 qname = &tname;
5470                                         }
5471                                 }
5472                                 /*
5473                                  * We could add an "else" clause here and
5474                                  * log that we're ignoring this rdataset.
5475                                  */
5476                         }
5477                         /*
5478                          * If wanted_chaining is true, we've done
5479                          * some chaining as the result of processing
5480                          * this node, and thus we need to set
5481                          * chaining to true.
5482                          *
5483                          * We don't set chaining inside of the
5484                          * rdataset loop because doing that would
5485                          * cause us to ignore the signatures of
5486                          * CNAMEs.
5487                          */
5488                         if (wanted_chaining)
5489                                 chaining = ISC_TRUE;
5490                 } else {
5491                         /*
5492                          * Look for a DNAME (or its SIG).  Anything else is
5493                          * ignored.
5494                          */
5495                         wanted_chaining = ISC_FALSE;
5496                         for (rdataset = ISC_LIST_HEAD(name->list);
5497                              rdataset != NULL;
5498                              rdataset = ISC_LIST_NEXT(rdataset, link)) {
5499                                 isc_boolean_t found_dname = ISC_FALSE;
5500                                 found = ISC_FALSE;
5501                                 aflag = 0;
5502                                 if (rdataset->type == dns_rdatatype_dname) {
5503                                         /*
5504                                          * We're looking for something else,
5505                                          * but we found a DNAME.
5506                                          *
5507                                          * If we're not chaining, then the
5508                                          * DNAME should not be external.
5509                                          */
5510                                         if (!chaining && external)
5511                                                 return (DNS_R_FORMERR);
5512                                         found = ISC_TRUE;
5513                                         want_chaining = ISC_TRUE;
5514                                         aflag = DNS_RDATASETATTR_ANSWER;
5515                                         result = dname_target(rdataset,
5516                                                               qname, name,
5517                                                               &dname);
5518                                         if (result == ISC_R_NOSPACE) {
5519                                                 /*
5520                                                  * We can't construct the
5521                                                  * DNAME target.  Do not
5522                                                  * try to continue.
5523                                                  */
5524                                                 want_chaining = ISC_FALSE;
5525                                         } else if (result != ISC_R_SUCCESS)
5526                                                 return (result);
5527                                         else
5528                                                 found_dname = ISC_TRUE;
5529                                 } else if (rdataset->type == dns_rdatatype_rrsig
5530                                            && rdataset->covers ==
5531                                            dns_rdatatype_dname) {
5532                                         /*
5533                                          * We've found a signature that
5534                                          * covers the DNAME.
5535                                          */
5536                                         found = ISC_TRUE;
5537                                         aflag = DNS_RDATASETATTR_ANSWERSIG;
5538                                 }
5539
5540                                 if (found) {
5541                                         /*
5542                                          * We've found an answer to our
5543                                          * question.
5544                                          */
5545                                         name->attributes |=
5546                                                 DNS_NAMEATTR_CACHE;
5547                                         rdataset->attributes |=
5548                                                 DNS_RDATASETATTR_CACHE;
5549                                         rdataset->trust = dns_trust_answer;
5550                                         if (!chaining) {
5551                                                 /*
5552                                                  * This data is "the" answer
5553                                                  * to our question only if
5554                                                  * we're not chaining.
5555                                                  */
5556                                                 INSIST(!external);
5557                                                 if (aflag ==
5558                                                     DNS_RDATASETATTR_ANSWER)
5559                                                         have_answer = ISC_TRUE;
5560                                                 name->attributes |=
5561                                                         DNS_NAMEATTR_ANSWER;
5562                                                 rdataset->attributes |= aflag;
5563                                                 if (aa)
5564                                                         rdataset->trust =
5565                                                           dns_trust_authanswer;
5566                                         } else if (external) {
5567                                                 rdataset->attributes |=
5568                                                     DNS_RDATASETATTR_EXTERNAL;
5569                                         }
5570
5571                                         /*
5572                                          * DNAME chaining.
5573                                          */
5574                                         if (found_dname) {
5575                                                 /*
5576                                                  * Copy the dname into the
5577                                                  * qname fixed name.
5578                                                  *
5579                                                  * Although we check for
5580                                                  * failure of the copy
5581                                                  * operation, in practice it
5582                                                  * should never fail since
5583                                                  * we already know that the
5584                                                  * result fits in a fixedname.
5585                                                  */
5586                                                 dns_fixedname_init(&fqname);
5587                                                 result = dns_name_copy(
5588                                                   dns_fixedname_name(&dname),
5589                                                   dns_fixedname_name(&fqname),
5590                                                   NULL);
5591                                                 if (result != ISC_R_SUCCESS)
5592                                                         return (result);
5593                                                 wanted_chaining = ISC_TRUE;
5594                                                 name->attributes |=
5595                                                         DNS_NAMEATTR_CHAINING;
5596                                                 rdataset->attributes |=
5597                                                     DNS_RDATASETATTR_CHAINING;
5598                                                 qname = dns_fixedname_name(
5599                                                                    &fqname);
5600                                         }
5601                                 }
5602                         }
5603                         if (wanted_chaining)
5604                                 chaining = ISC_TRUE;
5605                 }
5606                 result = dns_message_nextname(message, DNS_SECTION_ANSWER);
5607         }
5608         if (result == ISC_R_NOMORE)
5609                 result = ISC_R_SUCCESS;
5610         if (result != ISC_R_SUCCESS)
5611                 return (result);
5612
5613         /*
5614          * We should have found an answer.
5615          */
5616         if (!have_answer)
5617                 return (DNS_R_FORMERR);
5618
5619         /*
5620          * This response is now potentially cacheable.
5621          */
5622         fctx->attributes |= FCTX_ATTR_WANTCACHE;
5623
5624         /*
5625          * Did chaining end before we got the final answer?
5626          */
5627         if (chaining) {
5628                 /*
5629                  * Yes.  This may be a negative reply, so hand off
5630                  * authority section processing to the noanswer code.
5631                  * If it isn't a noanswer response, no harm will be
5632                  * done.
5633                  */
5634                 return (noanswer_response(fctx, qname, ISC_FALSE));
5635         }
5636
5637         /*
5638          * We didn't end with an incomplete chain, so the rcode should be
5639          * "no error".
5640          */
5641         if (message->rcode != dns_rcode_noerror)
5642                 return (DNS_R_FORMERR);
5643
5644         /*
5645          * Examine the authority section (if there is one).
5646          *
5647          * We expect there to be only one owner name for all the rdatasets
5648          * in this section, and we expect that it is not external.
5649          */
5650         done = ISC_FALSE;
5651         result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
5652         while (!done && result == ISC_R_SUCCESS) {
5653                 name = NULL;
5654                 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
5655                 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
5656                 if (!external) {
5657                         /*
5658                          * We expect to find NS or SIG NS rdatasets, and
5659                          * nothing else.
5660                          */
5661                         for (rdataset = ISC_LIST_HEAD(name->list);
5662                              rdataset != NULL;
5663                              rdataset = ISC_LIST_NEXT(rdataset, link)) {
5664                                 if (rdataset->type == dns_rdatatype_ns ||
5665                                     (rdataset->type == dns_rdatatype_rrsig &&
5666                                      rdataset->covers == dns_rdatatype_ns)) {
5667                                         name->attributes |=
5668                                                 DNS_NAMEATTR_CACHE;
5669                                         rdataset->attributes |=
5670                                                 DNS_RDATASETATTR_CACHE;
5671                                         if (aa && !chaining)
5672                                                 rdataset->trust =
5673                                                     dns_trust_authauthority;
5674                                         else
5675                                                 rdataset->trust =
5676                                                     dns_trust_additional;
5677
5678                                         /*
5679                                          * Mark any additional data related
5680                                          * to this rdataset.
5681                                          */
5682                                         (void)dns_rdataset_additionaldata(
5683                                                         rdataset,
5684                                                         check_related,
5685                                                         fctx);
5686                                         done = ISC_TRUE;
5687                                 }
5688                         }
5689                 }
5690                 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
5691         }
5692         if (result == ISC_R_NOMORE)
5693                 result = ISC_R_SUCCESS;
5694
5695         return (result);
5696 }
5697
5698 static void
5699 resume_dslookup(isc_task_t *task, isc_event_t *event) {
5700         dns_fetchevent_t *fevent;
5701         dns_resolver_t *res;
5702         fetchctx_t *fctx;
5703         isc_result_t result;
5704         isc_boolean_t bucket_empty = ISC_FALSE;
5705         isc_boolean_t locked = ISC_FALSE;
5706         unsigned int bucketnum;
5707         dns_rdataset_t nameservers;
5708         dns_fixedname_t fixed;
5709         dns_name_t *domain;
5710
5711         REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
5712         fevent = (dns_fetchevent_t *)event;
5713         fctx = event->ev_arg;
5714         REQUIRE(VALID_FCTX(fctx));
5715         res = fctx->res;
5716
5717         UNUSED(task);
5718         FCTXTRACE("resume_dslookup");
5719
5720         if (fevent->node != NULL)
5721                 dns_db_detachnode(fevent->db, &fevent->node);
5722         if (fevent->db != NULL)
5723                 dns_db_detach(&fevent->db);
5724
5725         dns_rdataset_init(&nameservers);
5726
5727         bucketnum = fctx->bucketnum;
5728         if (fevent->result == ISC_R_CANCELED) {
5729                 dns_resolver_destroyfetch(&fctx->nsfetch);
5730                 fctx_done(fctx, ISC_R_CANCELED, __LINE__);
5731         } else if (fevent->result == ISC_R_SUCCESS) {
5732
5733                 FCTXTRACE("resuming DS lookup");
5734
5735                 dns_resolver_destroyfetch(&fctx->nsfetch);
5736                 if (dns_rdataset_isassociated(&fctx->nameservers))
5737                         dns_rdataset_disassociate(&fctx->nameservers);
5738                 dns_rdataset_clone(fevent->rdataset, &fctx->nameservers);
5739                 dns_name_free(&fctx->domain,
5740                               fctx->res->buckets[bucketnum].mctx);
5741                 dns_name_init(&fctx->domain, NULL);
5742                 result = dns_name_dup(&fctx->nsname,
5743                                       fctx->res->buckets[bucketnum].mctx,
5744                                       &fctx->domain);
5745                 if (result != ISC_R_SUCCESS) {
5746                         fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
5747                         goto cleanup;
5748                 }
5749                 /*
5750                  * Try again.
5751                  */
5752                 fctx_try(fctx, ISC_TRUE);
5753         } else {
5754                 unsigned int n;
5755                 dns_rdataset_t *nsrdataset = NULL;
5756
5757                 /*
5758                  * Retrieve state from fctx->nsfetch before we destroy it.
5759                  */
5760                 dns_fixedname_init(&fixed);
5761                 domain = dns_fixedname_name(&fixed);
5762                 dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL);
5763                 if (dns_name_equal(&fctx->nsname, domain)) {
5764                         fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
5765                         dns_resolver_destroyfetch(&fctx->nsfetch);
5766                         goto cleanup;
5767                 }
5768                 if (dns_rdataset_isassociated(
5769                     &fctx->nsfetch->private->nameservers)) {
5770                         dns_rdataset_clone(
5771                             &fctx->nsfetch->private->nameservers,
5772                             &nameservers);
5773                         nsrdataset = &nameservers;
5774                 } else
5775                         domain = NULL;
5776                 dns_resolver_destroyfetch(&fctx->nsfetch);
5777                 n = dns_name_countlabels(&fctx->nsname);
5778                 dns_name_getlabelsequence(&fctx->nsname, 1, n - 1,
5779                                           &fctx->nsname);
5780
5781                 if (dns_rdataset_isassociated(fevent->rdataset))
5782                         dns_rdataset_disassociate(fevent->rdataset);
5783                 FCTXTRACE("continuing to look for parent's NS records");
5784                 result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
5785                                                   dns_rdatatype_ns, domain,
5786                                                   nsrdataset, NULL, 0, task,
5787                                                   resume_dslookup, fctx,
5788                                                   &fctx->nsrrset, NULL,
5789                                                   &fctx->nsfetch);
5790                 if (result != ISC_R_SUCCESS)
5791                         fctx_done(fctx, result, __LINE__);
5792                 else {
5793                         LOCK(&res->buckets[bucketnum].lock);
5794                         locked = ISC_TRUE;
5795                         fctx->references++;
5796                 }
5797         }
5798
5799  cleanup:
5800         if (dns_rdataset_isassociated(&nameservers))
5801                 dns_rdataset_disassociate(&nameservers);
5802         if (dns_rdataset_isassociated(fevent->rdataset))
5803                 dns_rdataset_disassociate(fevent->rdataset);
5804         INSIST(fevent->sigrdataset == NULL);
5805         isc_event_free(&event);
5806         if (!locked)
5807                 LOCK(&res->buckets[bucketnum].lock);
5808         fctx->references--;
5809         if (fctx->references == 0)
5810                 bucket_empty = fctx_destroy(fctx);
5811         UNLOCK(&res->buckets[bucketnum].lock);
5812         if (bucket_empty)
5813                 empty_bucket(res);
5814 }
5815
5816 static inline void
5817 checknamessection(dns_message_t *message, dns_section_t section) {
5818         isc_result_t result;
5819         dns_name_t *name;
5820         dns_rdata_t rdata = DNS_RDATA_INIT;
5821         dns_rdataset_t *rdataset;
5822
5823         for (result = dns_message_firstname(message, section);
5824              result == ISC_R_SUCCESS;
5825              result = dns_message_nextname(message, section))
5826         {
5827                 name = NULL;
5828                 dns_message_currentname(message, section, &name);
5829                 for (rdataset = ISC_LIST_HEAD(name->list);
5830                      rdataset != NULL;
5831                      rdataset = ISC_LIST_NEXT(rdataset, link)) {
5832                         for (result = dns_rdataset_first(rdataset);
5833                              result == ISC_R_SUCCESS;
5834                              result = dns_rdataset_next(rdataset)) {
5835                                 dns_rdataset_current(rdataset, &rdata);
5836                                 if (!dns_rdata_checkowner(name, rdata.rdclass,
5837                                                           rdata.type,
5838                                                           ISC_FALSE) ||
5839                                     !dns_rdata_checknames(&rdata, name, NULL))
5840                                 {
5841                                         rdataset->attributes |=
5842                                                 DNS_RDATASETATTR_CHECKNAMES;
5843                                 }
5844                                 dns_rdata_reset(&rdata);
5845                         }
5846                 }
5847         }
5848 }
5849
5850 static void
5851 checknames(dns_message_t *message) {
5852
5853         checknamessection(message, DNS_SECTION_ANSWER);
5854         checknamessection(message, DNS_SECTION_AUTHORITY);
5855         checknamessection(message, DNS_SECTION_ADDITIONAL);
5856 }
5857
5858 /*
5859  * Log server NSID at log level 'level'
5860  */
5861 static isc_result_t
5862 log_nsid(dns_rdataset_t *opt, resquery_t *query, int level, isc_mem_t *mctx)
5863 {
5864         static const char hex[17] = "0123456789abcdef";
5865         char addrbuf[ISC_SOCKADDR_FORMATSIZE];
5866         isc_uint16_t optcode, nsid_len, buflen, i;
5867         isc_result_t result;
5868         isc_buffer_t nsidbuf;
5869         dns_rdata_t rdata;
5870         unsigned char *p, *buf, *nsid;
5871
5872         /* Extract rdata from OPT rdataset */
5873         result = dns_rdataset_first(opt);
5874         if (result != ISC_R_SUCCESS)
5875                 return (ISC_R_FAILURE);
5876
5877         dns_rdata_init(&rdata);
5878         dns_rdataset_current(opt, &rdata);
5879         if (rdata.length < 4)
5880                 return (ISC_R_FAILURE);
5881
5882         /* Check for NSID */
5883         isc_buffer_init(&nsidbuf, rdata.data, rdata.length);
5884         isc_buffer_add(&nsidbuf, rdata.length);
5885         optcode = isc_buffer_getuint16(&nsidbuf);
5886         nsid_len = isc_buffer_getuint16(&nsidbuf);
5887         if (optcode != DNS_OPT_NSID || nsid_len == 0)
5888                 return (ISC_R_FAILURE);
5889
5890         /* Allocate buffer for storing hex version of the NSID */
5891         buflen = nsid_len * 2 + 1;
5892         buf = isc_mem_get(mctx, buflen);
5893         if (buf == NULL)
5894                 return (ISC_R_NOSPACE);
5895
5896         /* Convert to hex */
5897         p = buf;
5898         nsid = rdata.data + 4;
5899         for (i = 0; i < nsid_len; i++) {
5900                 *p++ = hex[(nsid[0] >> 4) & 0xf];
5901                 *p++ = hex[nsid[0] & 0xf];
5902                 nsid++;
5903         }
5904         *p = '\0';
5905
5906         isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
5907                             sizeof(addrbuf));
5908         isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
5909                       DNS_LOGMODULE_RESOLVER, level,
5910                       "received NSID '%s' from %s", buf, addrbuf);
5911
5912         /* Clean up */
5913         isc_mem_put(mctx, buf, buflen);
5914         return (ISC_R_SUCCESS);
5915 }
5916
5917 static void
5918 log_packet(dns_message_t *message, int level, isc_mem_t *mctx) {
5919         isc_buffer_t buffer;
5920         char *buf = NULL;
5921         int len = 1024;
5922         isc_result_t result;
5923
5924         if (! isc_log_wouldlog(dns_lctx, level))
5925                 return;
5926
5927         /*
5928          * Note that these are multiline debug messages.  We want a newline
5929          * to appear in the log after each message.
5930          */
5931
5932         do {
5933                 buf = isc_mem_get(mctx, len);
5934                 if (buf == NULL)
5935                         break;
5936                 isc_buffer_init(&buffer, buf, len);
5937                 result = dns_message_totext(message, &dns_master_style_debug,
5938                                             0, &buffer);
5939                 if (result == ISC_R_NOSPACE) {
5940                         isc_mem_put(mctx, buf, len);
5941                         len += 1024;
5942                 } else if (result == ISC_R_SUCCESS)
5943                         isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
5944                                       DNS_LOGMODULE_RESOLVER, level,
5945                                       "received packet:\n%.*s",
5946                                       (int)isc_buffer_usedlength(&buffer),
5947                                       buf);
5948         } while (result == ISC_R_NOSPACE);
5949
5950         if (buf != NULL)
5951                 isc_mem_put(mctx, buf, len);
5952 }
5953
5954 static void
5955 resquery_response(isc_task_t *task, isc_event_t *event) {
5956         isc_result_t result = ISC_R_SUCCESS;
5957         resquery_t *query = event->ev_arg;
5958         dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
5959         isc_boolean_t keep_trying, get_nameservers, resend;
5960         isc_boolean_t truncated;
5961         dns_message_t *message;
5962         dns_rdataset_t *opt;
5963         fetchctx_t *fctx;
5964         dns_name_t *fname;
5965         dns_fixedname_t foundname;
5966         isc_stdtime_t now;
5967         isc_time_t tnow, *finish;
5968         dns_adbaddrinfo_t *addrinfo;
5969         unsigned int options;
5970         unsigned int findoptions;
5971         isc_result_t broken_server;
5972         badnstype_t broken_type = badns_response;
5973
5974         REQUIRE(VALID_QUERY(query));
5975         fctx = query->fctx;
5976         options = query->options;
5977         REQUIRE(VALID_FCTX(fctx));
5978         REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
5979
5980         QTRACE("response");
5981
5982         if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET)
5983                 inc_stats(fctx->res, dns_resstatscounter_responsev4);
5984         else
5985                 inc_stats(fctx->res, dns_resstatscounter_responsev6);
5986
5987         (void)isc_timer_touch(fctx->timer);
5988
5989         keep_trying = ISC_FALSE;
5990         broken_server = ISC_R_SUCCESS;
5991         get_nameservers = ISC_FALSE;
5992         resend = ISC_FALSE;
5993         truncated = ISC_FALSE;
5994         finish = NULL;
5995
5996         if (fctx->res->exiting) {
5997                 result = ISC_R_SHUTTINGDOWN;
5998                 goto done;
5999         }
6000
6001         fctx->timeouts = 0;
6002         fctx->timeout = ISC_FALSE;
6003
6004         /*
6005          * XXXRTH  We should really get the current time just once.  We
6006          *              need a routine to convert from an isc_time_t to an
6007          *              isc_stdtime_t.
6008          */
6009         TIME_NOW(&tnow);
6010         finish = &tnow;
6011         isc_stdtime_get(&now);
6012
6013         /*
6014          * Did the dispatcher have a problem?
6015          */
6016         if (devent->result != ISC_R_SUCCESS) {
6017                 if (devent->result == ISC_R_EOF &&
6018                     (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
6019                         /*
6020                          * The problem might be that they
6021                          * don't understand EDNS0.  Turn it
6022                          * off and try again.
6023                          */
6024                         options |= DNS_FETCHOPT_NOEDNS0;
6025                         resend = ISC_TRUE;
6026                         /*
6027                          * Remember that they don't like EDNS0.
6028                          */
6029                         dns_adb_changeflags(fctx->adb,
6030                                             query->addrinfo,
6031                                             DNS_FETCHOPT_NOEDNS0,
6032                                             DNS_FETCHOPT_NOEDNS0);
6033                 } else {
6034                         /*
6035                          * There's no hope for this query.
6036                          */
6037                         keep_trying = ISC_TRUE;
6038
6039                         /*
6040                          * If this is a network error on an exclusive query
6041                          * socket, mark the server as bad so that we won't try
6042                          * it for this fetch again.
6043                          */
6044                         if (query->exclusivesocket &&
6045                             (devent->result == ISC_R_HOSTUNREACH ||
6046                              devent->result == ISC_R_NETUNREACH ||
6047                              devent->result == ISC_R_CONNREFUSED ||
6048                              devent->result == ISC_R_CANCELED)) {
6049                                     broken_server = devent->result;
6050                                     broken_type = badns_unreachable;
6051                         }
6052                 }
6053                 goto done;
6054         }
6055
6056         message = fctx->rmessage;
6057
6058         if (query->tsig != NULL) {
6059                 result = dns_message_setquerytsig(message, query->tsig);
6060                 if (result != ISC_R_SUCCESS)
6061                         goto done;
6062         }
6063
6064         if (query->tsigkey) {
6065                 result = dns_message_settsigkey(message, query->tsigkey);
6066                 if (result != ISC_R_SUCCESS)
6067                         goto done;
6068         }
6069
6070         result = dns_message_parse(message, &devent->buffer, 0);
6071         if (result != ISC_R_SUCCESS) {
6072                 switch (result) {
6073                 case ISC_R_UNEXPECTEDEND:
6074                         if (!message->question_ok ||
6075                             (message->flags & DNS_MESSAGEFLAG_TC) == 0 ||
6076                             (options & DNS_FETCHOPT_TCP) != 0) {
6077                                 /*
6078                                  * Either the message ended prematurely,
6079                                  * and/or wasn't marked as being truncated,
6080                                  * and/or this is a response to a query we
6081                                  * sent over TCP.  In all of these cases,
6082                                  * something is wrong with the remote
6083                                  * server and we don't want to retry using
6084                                  * TCP.
6085                                  */
6086                                 if ((query->options & DNS_FETCHOPT_NOEDNS0)
6087                                     == 0) {
6088                                         /*
6089                                          * The problem might be that they
6090                                          * don't understand EDNS0.  Turn it
6091                                          * off and try again.
6092                                          */
6093                                         options |= DNS_FETCHOPT_NOEDNS0;
6094                                         resend = ISC_TRUE;
6095                                         /*
6096                                          * Remember that they don't like EDNS0.
6097                                          */
6098                                         dns_adb_changeflags(
6099                                                         fctx->adb,
6100                                                         query->addrinfo,
6101                                                         DNS_FETCHOPT_NOEDNS0,
6102                                                         DNS_FETCHOPT_NOEDNS0);
6103                                         inc_stats(fctx->res,
6104                                                  dns_resstatscounter_edns0fail);
6105                                 } else {
6106                                         broken_server = result;
6107                                         keep_trying = ISC_TRUE;
6108                                 }
6109                                 goto done;
6110                         }
6111                         /*
6112                          * We defer retrying via TCP for a bit so we can
6113                          * check out this message further.
6114                          */
6115                         truncated = ISC_TRUE;
6116                         break;
6117                 case DNS_R_FORMERR:
6118                         if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
6119                                 /*
6120                                  * The problem might be that they
6121                                  * don't understand EDNS0.  Turn it
6122                                  * off and try again.
6123                                  */
6124                                 options |= DNS_FETCHOPT_NOEDNS0;
6125                                 resend = ISC_TRUE;
6126                                 /*
6127                                  * Remember that they don't like EDNS0.
6128                                  */
6129                                 dns_adb_changeflags(fctx->adb,
6130                                                     query->addrinfo,
6131                                                     DNS_FETCHOPT_NOEDNS0,
6132                                                     DNS_FETCHOPT_NOEDNS0);
6133                                 inc_stats(fctx->res,
6134                                                  dns_resstatscounter_edns0fail);
6135                         } else {
6136                                 broken_server = DNS_R_UNEXPECTEDRCODE;
6137                                 keep_trying = ISC_TRUE;
6138                         }
6139                         goto done;
6140                 default:
6141                         /*
6142                          * Something bad has happened.
6143                          */
6144                         goto done;
6145                 }
6146         }
6147
6148
6149         /*
6150          * Log the incoming packet.
6151          */
6152         log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx);
6153
6154         /*
6155          * Did we request NSID?  If so, and if the response contains
6156          * NSID data, log it at INFO level.
6157          */
6158         opt = dns_message_getopt(message);
6159         if (opt != NULL && (query->options & DNS_FETCHOPT_WANTNSID) != 0)
6160                 log_nsid(opt, query, ISC_LOG_INFO, fctx->res->mctx);
6161
6162         /*
6163          * If the message is signed, check the signature.  If not, this
6164          * returns success anyway.
6165          */
6166         result = dns_message_checksig(message, fctx->res->view);
6167         if (result != ISC_R_SUCCESS)
6168                 goto done;
6169
6170         /*
6171          * The dispatcher should ensure we only get responses with QR set.
6172          */
6173         INSIST((message->flags & DNS_MESSAGEFLAG_QR) != 0);
6174         /*
6175          * INSIST() that the message comes from the place we sent it to,
6176          * since the dispatch code should ensure this.
6177          *
6178          * INSIST() that the message id is correct (this should also be
6179          * ensured by the dispatch code).
6180          */
6181
6182
6183         /*
6184          * Deal with truncated responses by retrying using TCP.
6185          */
6186         if ((message->flags & DNS_MESSAGEFLAG_TC) != 0)
6187                 truncated = ISC_TRUE;
6188
6189         if (truncated) {
6190                 inc_stats(fctx->res, dns_resstatscounter_truncated);
6191                 if ((options & DNS_FETCHOPT_TCP) != 0) {
6192                         broken_server = DNS_R_TRUNCATEDTCP;
6193                         keep_trying = ISC_TRUE;
6194                 } else {
6195                         options |= DNS_FETCHOPT_TCP;
6196                         resend = ISC_TRUE;
6197                 }
6198                 goto done;
6199         }
6200
6201         /*
6202          * Is it a query response?
6203          */
6204         if (message->opcode != dns_opcode_query) {
6205                 /* XXXRTH Log */
6206                 broken_server = DNS_R_UNEXPECTEDOPCODE;
6207                 keep_trying = ISC_TRUE;
6208                 goto done;
6209         }
6210
6211         /*
6212          * Update statistics about erroneous responses.
6213          */
6214         if (message->rcode != dns_rcode_noerror) {
6215                 switch (message->rcode) {
6216                 case dns_rcode_nxdomain:
6217                         inc_stats(fctx->res, dns_resstatscounter_nxdomain);
6218                         break;
6219                 case dns_rcode_servfail:
6220                         inc_stats(fctx->res, dns_resstatscounter_servfail);
6221                         break;
6222                 case dns_rcode_formerr:
6223                         inc_stats(fctx->res, dns_resstatscounter_formerr);
6224                         break;
6225                 default:
6226                         inc_stats(fctx->res, dns_resstatscounter_othererror);
6227                         break;
6228                 }
6229         }
6230
6231         /*
6232          * Is the remote server broken, or does it dislike us?
6233          */
6234         if (message->rcode != dns_rcode_noerror &&
6235             message->rcode != dns_rcode_nxdomain) {
6236                 if (((message->rcode == dns_rcode_formerr ||
6237                      message->rcode == dns_rcode_notimp) ||
6238                     (message->rcode == dns_rcode_servfail &&
6239                      dns_message_getopt(message) == NULL)) &&
6240                     (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
6241                         /*
6242                          * It's very likely they don't like EDNS0.
6243                          * If the response code is SERVFAIL, also check if the
6244                          * response contains an OPT RR and don't cache the
6245                          * failure since it can be returned for various other
6246                          * reasons.
6247                          *
6248                          * XXXRTH  We should check if the question
6249                          *              we're asking requires EDNS0, and
6250                          *              if so, we should bail out.
6251                          */
6252                         options |= DNS_FETCHOPT_NOEDNS0;
6253                         resend = ISC_TRUE;
6254                         /*
6255                          * Remember that they don't like EDNS0.
6256                          */
6257                         if (message->rcode != dns_rcode_servfail)
6258                                 dns_adb_changeflags(fctx->adb, query->addrinfo,
6259                                                     DNS_FETCHOPT_NOEDNS0,
6260                                                     DNS_FETCHOPT_NOEDNS0);
6261                         inc_stats(fctx->res, dns_resstatscounter_edns0fail);
6262                 } else if (message->rcode == dns_rcode_formerr) {
6263                         if (ISFORWARDER(query->addrinfo)) {
6264                                 /*
6265                                  * This forwarder doesn't understand us,
6266                                  * but other forwarders might.  Keep trying.
6267                                  */
6268                                 broken_server = DNS_R_REMOTEFORMERR;
6269                                 keep_trying = ISC_TRUE;
6270                         } else {
6271                                 /*
6272                                  * The server doesn't understand us.  Since
6273                                  * all servers for a zone need similar
6274                                  * capabilities, we assume that we will get
6275                                  * FORMERR from all servers, and thus we
6276                                  * cannot make any more progress with this
6277                                  * fetch.
6278                                  */
6279                                 result = DNS_R_FORMERR;
6280                         }
6281                 } else if (message->rcode == dns_rcode_yxdomain) {
6282                         /*
6283                          * DNAME mapping failed because the new name
6284                          * was too long.  There's no chance of success
6285                          * for this fetch.
6286                          */
6287                         result = DNS_R_YXDOMAIN;
6288                 } else if (message->rcode == dns_rcode_badvers) {
6289                         unsigned int flags, mask;
6290                         unsigned int version;
6291
6292                         resend = ISC_TRUE;
6293                         version = (opt->ttl >> 16) & 0xff;
6294                         flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) |
6295                                 DNS_FETCHOPT_EDNSVERSIONSET;
6296                         mask = DNS_FETCHOPT_EDNSVERSIONMASK |
6297                                DNS_FETCHOPT_EDNSVERSIONSET;
6298                         switch (version) {
6299                         case 0:
6300                                 dns_adb_changeflags(fctx->adb, query->addrinfo,
6301                                                     flags, mask);
6302                                 break;
6303                         default:
6304                                 broken_server = DNS_R_BADVERS;
6305                                 keep_trying = ISC_TRUE;
6306                                 break;
6307                         }
6308                 } else {
6309                         /*
6310                          * XXXRTH log.
6311                          */
6312                         broken_server = DNS_R_UNEXPECTEDRCODE;
6313                         INSIST(broken_server != ISC_R_SUCCESS);
6314                         keep_trying = ISC_TRUE;
6315                 }
6316                 goto done;
6317         }
6318
6319         /*
6320          * Is the question the same as the one we asked?
6321          */
6322         result = same_question(fctx);
6323         if (result != ISC_R_SUCCESS) {
6324                 /* XXXRTH Log */
6325                 if (result == DNS_R_FORMERR)
6326                         keep_trying = ISC_TRUE;
6327                 goto done;
6328         }
6329
6330         /*
6331          * Is the server lame?
6332          */
6333         if (fctx->res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) &&
6334             is_lame(fctx)) {
6335                 inc_stats(fctx->res, dns_resstatscounter_lame);
6336                 log_lame(fctx, query->addrinfo);
6337                 result = dns_adb_marklame(fctx->adb, query->addrinfo,
6338                                           &fctx->name, fctx->type,
6339                                           now + fctx->res->lame_ttl);
6340                 if (result != ISC_R_SUCCESS)
6341                         isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
6342                                       DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR,
6343                                       "could not mark server as lame: %s",
6344                                       isc_result_totext(result));
6345                 broken_server = DNS_R_LAME;
6346                 keep_trying = ISC_TRUE;
6347                 goto done;
6348         }
6349
6350         /*
6351          * Enforce delegations only zones like NET and COM.
6352          */
6353         if (!ISFORWARDER(query->addrinfo) &&
6354             dns_view_isdelegationonly(fctx->res->view, &fctx->domain) &&
6355             !dns_name_equal(&fctx->domain, &fctx->name) &&
6356             fix_mustbedelegationornxdomain(message, fctx)) {
6357                 char namebuf[DNS_NAME_FORMATSIZE];
6358                 char domainbuf[DNS_NAME_FORMATSIZE];
6359                 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6360                 char classbuf[64];
6361                 char typebuf[64];
6362
6363                 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
6364                 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
6365                 dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
6366                 dns_rdataclass_format(fctx->res->rdclass, classbuf,
6367                                       sizeof(classbuf));
6368                 isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
6369                                     sizeof(addrbuf));
6370
6371                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DELEGATION_ONLY,
6372                              DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
6373                              "enforced delegation-only for '%s' (%s/%s/%s) "
6374                              "from %s",
6375                              domainbuf, namebuf, typebuf, classbuf, addrbuf);
6376         }
6377
6378         if ((fctx->res->options & DNS_RESOLVER_CHECKNAMES) != 0)
6379                 checknames(message);
6380
6381         /*
6382          * Clear cache bits.
6383          */
6384         fctx->attributes &= ~(FCTX_ATTR_WANTNCACHE | FCTX_ATTR_WANTCACHE);
6385
6386         /*
6387          * Did we get any answers?
6388          */
6389         if (message->counts[DNS_SECTION_ANSWER] > 0 &&
6390             (message->rcode == dns_rcode_noerror ||
6391              message->rcode == dns_rcode_nxdomain)) {
6392                 /*
6393                  * We've got answers.  However, if we sent
6394                  * a BIND 8 server an NS query, it may have
6395                  * incorrectly responded with a non-authoritative
6396                  * answer instead of a referral.  Since this
6397                  * answer lacks the SIGs necessary to do DNSSEC
6398                  * validation, we must invoke the following special
6399                  * kludge to treat it as a referral.
6400                  */
6401                 if (fctx->type == dns_rdatatype_ns &&
6402                     (message->flags & DNS_MESSAGEFLAG_AA) == 0 &&
6403                     !ISFORWARDER(query->addrinfo))
6404                 {
6405                         result = noanswer_response(fctx, NULL, ISC_TRUE);
6406                         if (result != DNS_R_DELEGATION) {
6407                                 /*
6408                                  * The answer section must have contained
6409                                  * something other than the NS records
6410                                  * we asked for.  Since AA is not set
6411                                  * and the server is not a forwarder,
6412                                  * it is technically lame and it's easier
6413                                  * to treat it as such than to figure out
6414                                  * some more elaborate course of action.
6415                                  */
6416                                 broken_server = DNS_R_LAME;
6417                                 keep_trying = ISC_TRUE;
6418                                 goto done;
6419                         }
6420                         goto force_referral;
6421                 }
6422                 result = answer_response(fctx);
6423                 if (result != ISC_R_SUCCESS) {
6424                         if (result == DNS_R_FORMERR)
6425                                 keep_trying = ISC_TRUE;
6426                         goto done;
6427                 }
6428         } else if (message->counts[DNS_SECTION_AUTHORITY] > 0 ||
6429                    message->rcode == dns_rcode_noerror ||
6430                    message->rcode == dns_rcode_nxdomain) {
6431                 /*
6432                  * NXDOMAIN, NXRDATASET, or referral.
6433                  */
6434                 result = noanswer_response(fctx, NULL, ISC_FALSE);
6435                 if (result == DNS_R_CHASEDSSERVERS) {
6436                 } else if (result == DNS_R_DELEGATION) {
6437                 force_referral:
6438                         /*
6439                          * We don't have the answer, but we know a better
6440                          * place to look.
6441                          */
6442                         get_nameservers = ISC_TRUE;
6443                         keep_trying = ISC_TRUE;
6444                         /*
6445                          * We have a new set of name servers, and it
6446                          * has not experienced any restarts yet.
6447                          */
6448                         fctx->restarts = 0;
6449
6450                         /*
6451                          * Update local statistics counters collected for each
6452                          * new zone.
6453                          */
6454                         fctx->referrals++;
6455                         fctx->querysent = 0;
6456                         fctx->lamecount = 0;
6457                         fctx->neterr = 0;
6458                         fctx->badresp = 0;
6459                         fctx->adberr = 0;
6460
6461                         result = ISC_R_SUCCESS;
6462                 } else if (result != ISC_R_SUCCESS) {
6463                         /*
6464                          * Something has gone wrong.
6465                          */
6466                         if (result == DNS_R_FORMERR)
6467                                 keep_trying = ISC_TRUE;
6468                         goto done;
6469                 }
6470         } else {
6471                 /*
6472                  * The server is insane.
6473                  */
6474                 /* XXXRTH Log */
6475                 broken_server = DNS_R_UNEXPECTEDRCODE;
6476                 keep_trying = ISC_TRUE;
6477                 goto done;
6478         }
6479
6480         /*
6481          * Follow additional section data chains.
6482          */
6483         chase_additional(fctx);
6484
6485         /*
6486          * Cache the cacheable parts of the message.  This may also cause
6487          * work to be queued to the DNSSEC validator.
6488          */
6489         if (WANTCACHE(fctx)) {
6490                 result = cache_message(fctx, query->addrinfo, now);
6491                 if (result != ISC_R_SUCCESS)
6492                         goto done;
6493         }
6494
6495         /*
6496          * Ncache the negatively cacheable parts of the message.  This may
6497          * also cause work to be queued to the DNSSEC validator.
6498          */
6499         if (WANTNCACHE(fctx)) {
6500                 dns_rdatatype_t covers;
6501                 if (message->rcode == dns_rcode_nxdomain)
6502                         covers = dns_rdatatype_any;
6503                 else
6504                         covers = fctx->type;
6505
6506                 /*
6507                  * Cache any negative cache entries in the message.
6508                  */
6509                 result = ncache_message(fctx, query->addrinfo, covers, now);
6510         }
6511
6512  done:
6513         /*
6514          * Remember the query's addrinfo, in case we need to mark the
6515          * server as broken.
6516          */
6517         addrinfo = query->addrinfo;
6518
6519         /*
6520          * Cancel the query.
6521          *
6522          * XXXRTH  Don't cancel the query if waiting for validation?
6523          */
6524         fctx_cancelquery(&query, &devent, finish, ISC_FALSE);
6525
6526         if (keep_trying) {
6527                 if (result == DNS_R_FORMERR)
6528                         broken_server = DNS_R_FORMERR;
6529                 if (broken_server != ISC_R_SUCCESS) {
6530                         /*
6531                          * Add this server to the list of bad servers for
6532                          * this fctx.
6533                          */
6534                         add_bad(fctx, addrinfo, broken_server, broken_type);
6535                 }
6536
6537                 if (get_nameservers) {
6538                         dns_name_t *name;
6539                         dns_fixedname_init(&foundname);
6540                         fname = dns_fixedname_name(&foundname);
6541                         if (result != ISC_R_SUCCESS) {
6542                                 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
6543                                 return;
6544                         }
6545                         findoptions = 0;
6546                         if (dns_rdatatype_atparent(fctx->type))
6547                                 findoptions |= DNS_DBFIND_NOEXACT;
6548                         if ((options & DNS_FETCHOPT_UNSHARED) == 0)
6549                                 name = &fctx->name;
6550                         else
6551                                 name = &fctx->domain;
6552                         result = dns_view_findzonecut(fctx->res->view,
6553                                                       name, fname,
6554                                                       now, findoptions,
6555                                                       ISC_TRUE,
6556                                                       &fctx->nameservers,
6557                                                       NULL);
6558                         if (result != ISC_R_SUCCESS) {
6559                                 FCTXTRACE("couldn't find a zonecut");
6560                                 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
6561                                 return;
6562                         }
6563                         if (!dns_name_issubdomain(fname, &fctx->domain)) {
6564                                 /*
6565                                  * The best nameservers are now above our
6566                                  * QDOMAIN.
6567                                  */
6568                                 FCTXTRACE("nameservers now above QDOMAIN");
6569                                 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
6570                                 return;
6571                         }
6572                         dns_name_free(&fctx->domain,
6573                                       fctx->res->buckets[fctx->bucketnum].mctx);
6574                         dns_name_init(&fctx->domain, NULL);
6575                         result = dns_name_dup(fname,
6576                                               fctx->res->buckets[fctx->bucketnum].mctx,
6577                                               &fctx->domain);
6578                         if (result != ISC_R_SUCCESS) {
6579                                 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
6580                                 return;
6581                         }
6582                         fctx_cancelqueries(fctx, ISC_TRUE);
6583                         fctx_cleanupfinds(fctx);
6584                         fctx_cleanupaltfinds(fctx);
6585                         fctx_cleanupforwaddrs(fctx);
6586                         fctx_cleanupaltaddrs(fctx);
6587                 }
6588                 /*
6589                  * Try again.
6590                  */
6591                 fctx_try(fctx, !get_nameservers);
6592         } else if (resend) {
6593                 /*
6594                  * Resend (probably with changed options).
6595                  */
6596                 FCTXTRACE("resend");
6597                 inc_stats(fctx->res, dns_resstatscounter_retry);
6598                 result = fctx_query(fctx, addrinfo, options);
6599                 if (result != ISC_R_SUCCESS)
6600                         fctx_done(fctx, result, __LINE__);
6601         } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) {
6602                 /*
6603                  * All has gone well so far, but we are waiting for the
6604                  * DNSSEC validator to validate the answer.
6605                  */
6606                 FCTXTRACE("wait for validator");
6607                 fctx_cancelqueries(fctx, ISC_TRUE);
6608                 /*
6609                  * We must not retransmit while the validator is working;
6610                  * it has references to the current rmessage.
6611                  */
6612                 result = fctx_stopidletimer(fctx);
6613                 if (result != ISC_R_SUCCESS)
6614                         fctx_done(fctx, result, __LINE__);
6615         } else if (result == DNS_R_CHASEDSSERVERS) {
6616                 unsigned int n;
6617                 add_bad(fctx, addrinfo, result, broken_type);
6618                 fctx_cancelqueries(fctx, ISC_TRUE);
6619                 fctx_cleanupfinds(fctx);
6620                 fctx_cleanupforwaddrs(fctx);
6621
6622                 n = dns_name_countlabels(&fctx->name);
6623                 dns_name_getlabelsequence(&fctx->name, 1, n - 1, &fctx->nsname);
6624
6625                 FCTXTRACE("suspending DS lookup to find parent's NS records");
6626
6627                 result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
6628                                                   dns_rdatatype_ns,
6629                                                   NULL, NULL, NULL, 0, task,
6630                                                   resume_dslookup, fctx,
6631                                                   &fctx->nsrrset, NULL,
6632                                                   &fctx->nsfetch);
6633                 if (result != ISC_R_SUCCESS)
6634                         fctx_done(fctx, result, __LINE__);
6635                 LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
6636                 fctx->references++;
6637                 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
6638                 result = fctx_stopidletimer(fctx);
6639                 if (result != ISC_R_SUCCESS)
6640                         fctx_done(fctx, result, __LINE__);
6641         } else {
6642                 /*
6643                  * We're done.
6644                  */
6645                 fctx_done(fctx, result, __LINE__);
6646         }
6647 }
6648
6649
6650 /***
6651  *** Resolver Methods
6652  ***/
6653
6654 static void
6655 destroy(dns_resolver_t *res) {
6656         unsigned int i;
6657         alternate_t *a;
6658
6659         REQUIRE(res->references == 0);
6660         REQUIRE(!res->priming);
6661         REQUIRE(res->primefetch == NULL);
6662
6663         RTRACE("destroy");
6664
6665         INSIST(res->nfctx == 0);
6666
6667         DESTROYLOCK(&res->primelock);
6668         DESTROYLOCK(&res->nlock);
6669         DESTROYLOCK(&res->lock);
6670         for (i = 0; i < res->nbuckets; i++) {
6671                 INSIST(ISC_LIST_EMPTY(res->buckets[i].fctxs));
6672                 isc_task_shutdown(res->buckets[i].task);
6673                 isc_task_detach(&res->buckets[i].task);
6674                 DESTROYLOCK(&res->buckets[i].lock);
6675                 isc_mem_detach(&res->buckets[i].mctx);
6676         }
6677         isc_mem_put(res->mctx, res->buckets,
6678                     res->nbuckets * sizeof(fctxbucket_t));
6679         if (res->dispatchv4 != NULL)
6680                 dns_dispatch_detach(&res->dispatchv4);
6681         if (res->dispatchv6 != NULL)
6682                 dns_dispatch_detach(&res->dispatchv6);
6683         while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) {
6684                 ISC_LIST_UNLINK(res->alternates, a, link);
6685                 if (!a->isaddress)
6686                         dns_name_free(&a->_u._n.name, res->mctx);
6687                 isc_mem_put(res->mctx, a, sizeof(*a));
6688         }
6689         dns_resolver_reset_algorithms(res);
6690         dns_resolver_resetmustbesecure(res);
6691 #if USE_ALGLOCK
6692         isc_rwlock_destroy(&res->alglock);
6693 #endif
6694 #if USE_MBSLOCK
6695         isc_rwlock_destroy(&res->mbslock);
6696 #endif
6697         isc_timer_detach(&res->spillattimer);
6698         res->magic = 0;
6699         isc_mem_put(res->mctx, res, sizeof(*res));
6700 }
6701
6702 static void
6703 send_shutdown_events(dns_resolver_t *res) {
6704         isc_event_t *event, *next_event;
6705         isc_task_t *etask;
6706
6707         /*
6708          * Caller must be holding the resolver lock.
6709          */
6710
6711         for (event = ISC_LIST_HEAD(res->whenshutdown);
6712              event != NULL;
6713              event = next_event) {
6714                 next_event = ISC_LIST_NEXT(event, ev_link);
6715                 ISC_LIST_UNLINK(res->whenshutdown, event, ev_link);
6716                 etask = event->ev_sender;
6717                 event->ev_sender = res;
6718                 isc_task_sendanddetach(&etask, &event);
6719         }
6720 }
6721
6722 static void
6723 empty_bucket(dns_resolver_t *res) {
6724         RTRACE("empty_bucket");
6725
6726         LOCK(&res->lock);
6727
6728         INSIST(res->activebuckets > 0);
6729         res->activebuckets--;
6730         if (res->activebuckets == 0)
6731                 send_shutdown_events(res);
6732
6733         UNLOCK(&res->lock);
6734 }
6735
6736 static void
6737 spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
6738         dns_resolver_t *res = event->ev_arg;
6739         isc_result_t result;
6740         unsigned int count;
6741         isc_boolean_t logit = ISC_FALSE;
6742
6743         REQUIRE(VALID_RESOLVER(res));
6744
6745         UNUSED(task);
6746
6747         LOCK(&res->lock);
6748         INSIST(!res->exiting);
6749         if (res->spillat > res->spillatmin) {
6750                 res->spillat--;
6751                 logit = ISC_TRUE;
6752         }
6753         if (res->spillat <= res->spillatmin) {
6754                 result = isc_timer_reset(res->spillattimer,
6755                                          isc_timertype_inactive, NULL,
6756                                          NULL, ISC_TRUE);
6757                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6758         }
6759         count = res->spillat;
6760         UNLOCK(&res->lock);
6761         if (logit)
6762                 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
6763                               DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
6764                               "clients-per-query decreased to %u", count);
6765
6766         isc_event_free(&event);
6767 }
6768
6769 isc_result_t
6770 dns_resolver_create(dns_view_t *view,
6771                     isc_taskmgr_t *taskmgr, unsigned int ntasks,
6772                     isc_socketmgr_t *socketmgr,
6773                     isc_timermgr_t *timermgr,
6774                     unsigned int options,
6775                     dns_dispatchmgr_t *dispatchmgr,
6776                     dns_dispatch_t *dispatchv4,
6777                     dns_dispatch_t *dispatchv6,
6778                     dns_resolver_t **resp)
6779 {
6780         dns_resolver_t *res;
6781         isc_result_t result = ISC_R_SUCCESS;
6782         unsigned int i, buckets_created = 0;
6783         isc_task_t *task = NULL;
6784         char name[16];
6785         unsigned dispattr;
6786
6787         /*
6788          * Create a resolver.
6789          */
6790
6791         REQUIRE(DNS_VIEW_VALID(view));
6792         REQUIRE(ntasks > 0);
6793         REQUIRE(resp != NULL && *resp == NULL);
6794         REQUIRE(dispatchmgr != NULL);
6795         REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
6796
6797         res = isc_mem_get(view->mctx, sizeof(*res));
6798         if (res == NULL)
6799                 return (ISC_R_NOMEMORY);
6800         RTRACE("create");
6801         res->mctx = view->mctx;
6802         res->rdclass = view->rdclass;
6803         res->socketmgr = socketmgr;
6804         res->timermgr = timermgr;
6805         res->taskmgr = taskmgr;
6806         res->dispatchmgr = dispatchmgr;
6807         res->view = view;
6808         res->options = options;
6809         res->lame_ttl = 0;
6810         ISC_LIST_INIT(res->alternates);
6811         res->udpsize = RECV_BUFFER_SIZE;
6812         res->algorithms = NULL;
6813         res->mustbesecure = NULL;
6814         res->spillatmin = res->spillat = 10;
6815         res->spillatmax = 100;
6816         res->spillattimer = NULL;
6817         res->zero_no_soa_ttl = ISC_FALSE;
6818         res->ndisps = 0;
6819         res->nextdisp = 0; /* meaningless at this point, but init it */
6820         res->nbuckets = ntasks;
6821         res->activebuckets = ntasks;
6822         res->buckets = isc_mem_get(view->mctx,
6823                                    ntasks * sizeof(fctxbucket_t));
6824         if (res->buckets == NULL) {
6825                 result = ISC_R_NOMEMORY;
6826                 goto cleanup_res;
6827         }
6828         for (i = 0; i < ntasks; i++) {
6829                 result = isc_mutex_init(&res->buckets[i].lock);
6830                 if (result != ISC_R_SUCCESS)
6831                         goto cleanup_buckets;
6832                 res->buckets[i].task = NULL;
6833                 result = isc_task_create(taskmgr, 0, &res->buckets[i].task);
6834                 if (result != ISC_R_SUCCESS) {
6835                         DESTROYLOCK(&res->buckets[i].lock);
6836                         goto cleanup_buckets;
6837                 }
6838                 res->buckets[i].mctx = NULL;
6839                 snprintf(name, sizeof(name), "res%u", i);
6840 #ifdef ISC_PLATFORM_USETHREADS
6841                 /*
6842                  * Use a separate memory context for each bucket to reduce
6843                  * contention among multiple threads.  Do this only when
6844                  * enabling threads because it will be require more memory.
6845                  */
6846                 result = isc_mem_create(0, 0, &res->buckets[i].mctx);
6847                 if (result != ISC_R_SUCCESS) {
6848                         isc_task_detach(&res->buckets[i].task);
6849                         DESTROYLOCK(&res->buckets[i].lock);
6850                         goto cleanup_buckets;
6851                 }
6852                 isc_mem_setname(res->buckets[i].mctx, name, NULL);
6853 #else
6854                 isc_mem_attach(view->mctx, &res->buckets[i].mctx);
6855 #endif
6856                 isc_task_setname(res->buckets[i].task, name, res);
6857                 ISC_LIST_INIT(res->buckets[i].fctxs);
6858                 res->buckets[i].exiting = ISC_FALSE;
6859                 buckets_created++;
6860         }
6861
6862         res->dispatchv4 = NULL;
6863         if (dispatchv4 != NULL) {
6864                 dns_dispatch_attach(dispatchv4, &res->dispatchv4);
6865                 dispattr = dns_dispatch_getattributes(dispatchv4);
6866                 res->exclusivev4 =
6867                         ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0);
6868         }
6869
6870         res->dispatchv6 = NULL;
6871         if (dispatchv6 != NULL) {
6872                 dns_dispatch_attach(dispatchv6, &res->dispatchv6);
6873                 dispattr = dns_dispatch_getattributes(dispatchv6);
6874                 res->exclusivev6 =
6875                         ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0);
6876         }
6877
6878         res->references = 1;
6879         res->exiting = ISC_FALSE;
6880         res->frozen = ISC_FALSE;
6881         ISC_LIST_INIT(res->whenshutdown);
6882         res->priming = ISC_FALSE;
6883         res->primefetch = NULL;
6884         res->nfctx = 0;
6885
6886         result = isc_mutex_init(&res->lock);
6887         if (result != ISC_R_SUCCESS)
6888                 goto cleanup_dispatches;
6889
6890         result = isc_mutex_init(&res->nlock);
6891         if (result != ISC_R_SUCCESS)
6892                 goto cleanup_lock;
6893
6894         result = isc_mutex_init(&res->primelock);
6895         if (result != ISC_R_SUCCESS)
6896                 goto cleanup_nlock;
6897
6898         task = NULL;
6899         result = isc_task_create(taskmgr, 0, &task);
6900         if (result != ISC_R_SUCCESS)
6901                 goto cleanup_primelock;
6902
6903         result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
6904                                   task, spillattimer_countdown, res,
6905                                   &res->spillattimer);
6906         isc_task_detach(&task);
6907         if (result != ISC_R_SUCCESS)
6908                 goto cleanup_primelock;
6909
6910 #if USE_ALGLOCK
6911         result = isc_rwlock_init(&res->alglock, 0, 0);
6912         if (result != ISC_R_SUCCESS)
6913                 goto cleanup_spillattimer;
6914 #endif
6915 #if USE_MBSLOCK
6916         result = isc_rwlock_init(&res->mbslock, 0, 0);
6917         if (result != ISC_R_SUCCESS)
6918                 goto cleanup_alglock;
6919 #endif
6920
6921         res->magic = RES_MAGIC;
6922
6923         *resp = res;
6924
6925         return (ISC_R_SUCCESS);
6926
6927 #if USE_MBSLOCK
6928  cleanup_alglock:
6929 #if USE_ALGLOCK
6930         isc_rwlock_destroy(&res->alglock);
6931 #endif
6932 #endif
6933 #if USE_ALGLOCK || USE_MBSLOCK
6934  cleanup_spillattimer:
6935         isc_timer_detach(&res->spillattimer);
6936 #endif
6937
6938  cleanup_primelock:
6939         DESTROYLOCK(&res->primelock);
6940
6941  cleanup_nlock:
6942         DESTROYLOCK(&res->nlock);
6943
6944  cleanup_lock:
6945         DESTROYLOCK(&res->lock);
6946
6947  cleanup_dispatches:
6948         if (res->dispatchv6 != NULL)
6949                 dns_dispatch_detach(&res->dispatchv6);
6950         if (res->dispatchv4 != NULL)
6951                 dns_dispatch_detach(&res->dispatchv4);
6952
6953  cleanup_buckets:
6954         for (i = 0; i < buckets_created; i++) {
6955                 isc_mem_detach(&res->buckets[i].mctx);
6956                 DESTROYLOCK(&res->buckets[i].lock);
6957                 isc_task_shutdown(res->buckets[i].task);
6958                 isc_task_detach(&res->buckets[i].task);
6959         }
6960         isc_mem_put(view->mctx, res->buckets,
6961                     res->nbuckets * sizeof(fctxbucket_t));
6962
6963  cleanup_res:
6964         isc_mem_put(view->mctx, res, sizeof(*res));
6965
6966         return (result);
6967 }
6968
6969 static void
6970 prime_done(isc_task_t *task, isc_event_t *event) {
6971         dns_resolver_t *res;
6972         dns_fetchevent_t *fevent;
6973         dns_fetch_t *fetch;
6974         dns_db_t *db = NULL;
6975
6976         REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
6977         fevent = (dns_fetchevent_t *)event;
6978         res = event->ev_arg;
6979         REQUIRE(VALID_RESOLVER(res));
6980
6981         UNUSED(task);
6982
6983         LOCK(&res->lock);
6984
6985         INSIST(res->priming);
6986         res->priming = ISC_FALSE;
6987         LOCK(&res->primelock);
6988         fetch = res->primefetch;
6989         res->primefetch = NULL;
6990         UNLOCK(&res->primelock);
6991
6992         UNLOCK(&res->lock);
6993
6994         if (fevent->result == ISC_R_SUCCESS &&
6995             res->view->cache != NULL && res->view->hints != NULL) {
6996                 dns_cache_attachdb(res->view->cache, &db);
6997                 dns_root_checkhints(res->view, res->view->hints, db);
6998                 dns_db_detach(&db);
6999         }
7000
7001         if (fevent->node != NULL)
7002                 dns_db_detachnode(fevent->db, &fevent->node);
7003         if (fevent->db != NULL)
7004                 dns_db_detach(&fevent->db);
7005         if (dns_rdataset_isassociated(fevent->rdataset))
7006                 dns_rdataset_disassociate(fevent->rdataset);
7007         INSIST(fevent->sigrdataset == NULL);
7008
7009         isc_mem_put(res->mctx, fevent->rdataset, sizeof(*fevent->rdataset));
7010
7011         isc_event_free(&event);
7012         dns_resolver_destroyfetch(&fetch);
7013 }
7014
7015 void
7016 dns_resolver_prime(dns_resolver_t *res) {
7017         isc_boolean_t want_priming = ISC_FALSE;
7018         dns_rdataset_t *rdataset;
7019         isc_result_t result;
7020
7021         REQUIRE(VALID_RESOLVER(res));
7022         REQUIRE(res->frozen);
7023
7024         RTRACE("dns_resolver_prime");
7025
7026         LOCK(&res->lock);
7027
7028         if (!res->exiting && !res->priming) {
7029                 INSIST(res->primefetch == NULL);
7030                 res->priming = ISC_TRUE;
7031                 want_priming = ISC_TRUE;
7032         }
7033
7034         UNLOCK(&res->lock);
7035
7036         if (want_priming) {
7037                 /*
7038                  * To avoid any possible recursive locking problems, we
7039                  * start the priming fetch like any other fetch, and holding
7040                  * no resolver locks.  No one else will try to start it
7041                  * because we're the ones who set res->priming to true.
7042                  * Any other callers of dns_resolver_prime() while we're
7043                  * running will see that res->priming is already true and
7044                  * do nothing.
7045                  */
7046                 RTRACE("priming");
7047                 rdataset = isc_mem_get(res->mctx, sizeof(*rdataset));
7048                 if (rdataset == NULL) {
7049                         LOCK(&res->lock);
7050                         INSIST(res->priming);
7051                         INSIST(res->primefetch == NULL);
7052                         res->priming = ISC_FALSE;
7053                         UNLOCK(&res->lock);
7054                         return;
7055                 }
7056                 dns_rdataset_init(rdataset);
7057                 LOCK(&res->primelock);
7058                 result = dns_resolver_createfetch(res, dns_rootname,
7059                                                   dns_rdatatype_ns,
7060                                                   NULL, NULL, NULL, 0,
7061                                                   res->buckets[0].task,
7062                                                   prime_done,
7063                                                   res, rdataset, NULL,
7064                                                   &res->primefetch);
7065                 UNLOCK(&res->primelock);
7066                 if (result != ISC_R_SUCCESS) {
7067                         LOCK(&res->lock);
7068                         INSIST(res->priming);
7069                         res->priming = ISC_FALSE;
7070                         UNLOCK(&res->lock);
7071                 }
7072         }
7073 }
7074
7075 void
7076 dns_resolver_freeze(dns_resolver_t *res) {
7077
7078         /*
7079          * Freeze resolver.
7080          */
7081
7082         REQUIRE(VALID_RESOLVER(res));
7083         REQUIRE(!res->frozen);
7084
7085         res->frozen = ISC_TRUE;
7086 }
7087
7088 void
7089 dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) {
7090         REQUIRE(VALID_RESOLVER(source));
7091         REQUIRE(targetp != NULL && *targetp == NULL);
7092
7093         RRTRACE(source, "attach");
7094         LOCK(&source->lock);
7095         REQUIRE(!source->exiting);
7096
7097         INSIST(source->references > 0);
7098         source->references++;
7099         INSIST(source->references != 0);
7100         UNLOCK(&source->lock);
7101
7102         *targetp = source;
7103 }
7104
7105 void
7106 dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
7107                           isc_event_t **eventp)
7108 {
7109         isc_task_t *clone;
7110         isc_event_t *event;
7111
7112         REQUIRE(VALID_RESOLVER(res));
7113         REQUIRE(eventp != NULL);
7114
7115         event = *eventp;
7116         *eventp = NULL;
7117
7118         LOCK(&res->lock);
7119
7120         if (res->exiting && res->activebuckets == 0) {
7121                 /*
7122                  * We're already shutdown.  Send the event.
7123                  */
7124                 event->ev_sender = res;
7125                 isc_task_send(task, &event);
7126         } else {
7127                 clone = NULL;
7128                 isc_task_attach(task, &clone);
7129                 event->ev_sender = clone;
7130                 ISC_LIST_APPEND(res->whenshutdown, event, ev_link);
7131         }
7132
7133         UNLOCK(&res->lock);
7134 }
7135
7136 void
7137 dns_resolver_shutdown(dns_resolver_t *res) {
7138         unsigned int i;
7139         fetchctx_t *fctx;
7140         isc_socket_t *sock;
7141         isc_result_t result;
7142
7143         REQUIRE(VALID_RESOLVER(res));
7144
7145         RTRACE("shutdown");
7146
7147         LOCK(&res->lock);
7148
7149         if (!res->exiting) {
7150                 RTRACE("exiting");
7151                 res->exiting = ISC_TRUE;
7152
7153                 for (i = 0; i < res->nbuckets; i++) {
7154                         LOCK(&res->buckets[i].lock);
7155                         for (fctx = ISC_LIST_HEAD(res->buckets[i].fctxs);
7156                              fctx != NULL;
7157                              fctx = ISC_LIST_NEXT(fctx, link))
7158                                 fctx_shutdown(fctx);
7159                         if (res->dispatchv4 != NULL && !res->exclusivev4) {
7160                                 sock = dns_dispatch_getsocket(res->dispatchv4);
7161                                 isc_socket_cancel(sock, res->buckets[i].task,
7162                                                   ISC_SOCKCANCEL_ALL);
7163                         }
7164                         if (res->dispatchv6 != NULL && !res->exclusivev6) {
7165                                 sock = dns_dispatch_getsocket(res->dispatchv6);
7166                                 isc_socket_cancel(sock, res->buckets[i].task,
7167                                                   ISC_SOCKCANCEL_ALL);
7168                         }
7169                         res->buckets[i].exiting = ISC_TRUE;
7170                         if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) {
7171                                 INSIST(res->activebuckets > 0);
7172                                 res->activebuckets--;
7173                         }
7174                         UNLOCK(&res->buckets[i].lock);
7175                 }
7176                 if (res->activebuckets == 0)
7177                         send_shutdown_events(res);
7178                 result = isc_timer_reset(res->spillattimer,
7179                                          isc_timertype_inactive, NULL,
7180                                          NULL, ISC_TRUE);
7181                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7182         }
7183
7184         UNLOCK(&res->lock);
7185 }
7186
7187 void
7188 dns_resolver_detach(dns_resolver_t **resp) {
7189         dns_resolver_t *res;
7190         isc_boolean_t need_destroy = ISC_FALSE;
7191
7192         REQUIRE(resp != NULL);
7193         res = *resp;
7194         REQUIRE(VALID_RESOLVER(res));
7195
7196         RTRACE("detach");
7197
7198         LOCK(&res->lock);
7199
7200         INSIST(res->references > 0);
7201         res->references--;
7202         if (res->references == 0) {
7203                 INSIST(res->exiting && res->activebuckets == 0);
7204                 need_destroy = ISC_TRUE;
7205         }
7206
7207         UNLOCK(&res->lock);
7208
7209         if (need_destroy)
7210                 destroy(res);
7211
7212         *resp = NULL;
7213 }
7214
7215 static inline isc_boolean_t
7216 fctx_match(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
7217            unsigned int options)
7218 {
7219         if (fctx->type != type || fctx->options != options)
7220                 return (ISC_FALSE);
7221         return (dns_name_equal(&fctx->name, name));
7222 }
7223
7224 static inline void
7225 log_fetch(dns_name_t *name, dns_rdatatype_t type) {
7226         char namebuf[DNS_NAME_FORMATSIZE];
7227         char typebuf[DNS_RDATATYPE_FORMATSIZE];
7228         int level = ISC_LOG_DEBUG(1);
7229
7230         if (! isc_log_wouldlog(dns_lctx, level))
7231                 return;
7232
7233         dns_name_format(name, namebuf, sizeof(namebuf));
7234         dns_rdatatype_format(type, typebuf, sizeof(typebuf));
7235
7236         isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
7237                       DNS_LOGMODULE_RESOLVER, level,
7238                       "createfetch: %s %s", namebuf, typebuf);
7239 }
7240
7241 isc_result_t
7242 dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name,
7243                          dns_rdatatype_t type,
7244                          dns_name_t *domain, dns_rdataset_t *nameservers,
7245                          dns_forwarders_t *forwarders,
7246                          unsigned int options, isc_task_t *task,
7247                          isc_taskaction_t action, void *arg,
7248                          dns_rdataset_t *rdataset,
7249                          dns_rdataset_t *sigrdataset,
7250                          dns_fetch_t **fetchp)
7251 {
7252         return (dns_resolver_createfetch2(res, name, type, domain,
7253                                           nameservers, forwarders, NULL, 0,
7254                                           options, task, action, arg,
7255                                           rdataset, sigrdataset, fetchp));
7256 }
7257
7258 isc_result_t
7259 dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name,
7260                           dns_rdatatype_t type,
7261                           dns_name_t *domain, dns_rdataset_t *nameservers,
7262                           dns_forwarders_t *forwarders,
7263                           isc_sockaddr_t *client, dns_messageid_t id,
7264                           unsigned int options, isc_task_t *task,
7265                           isc_taskaction_t action, void *arg,
7266                           dns_rdataset_t *rdataset,
7267                           dns_rdataset_t *sigrdataset,
7268                           dns_fetch_t **fetchp)
7269 {
7270         dns_fetch_t *fetch;
7271         fetchctx_t *fctx = NULL;
7272         isc_result_t result = ISC_R_SUCCESS;
7273         unsigned int bucketnum;
7274         isc_boolean_t new_fctx = ISC_FALSE;
7275         isc_event_t *event;
7276         unsigned int count = 0;
7277         unsigned int spillat;
7278         unsigned int spillatmin;
7279
7280         UNUSED(forwarders);
7281
7282         REQUIRE(VALID_RESOLVER(res));
7283         REQUIRE(res->frozen);
7284         /* XXXRTH  Check for meta type */
7285         if (domain != NULL) {
7286                 REQUIRE(DNS_RDATASET_VALID(nameservers));
7287                 REQUIRE(nameservers->type == dns_rdatatype_ns);
7288         } else
7289                 REQUIRE(nameservers == NULL);
7290         REQUIRE(forwarders == NULL);
7291         REQUIRE(!dns_rdataset_isassociated(rdataset));
7292         REQUIRE(sigrdataset == NULL ||
7293                 !dns_rdataset_isassociated(sigrdataset));
7294         REQUIRE(fetchp != NULL && *fetchp == NULL);
7295
7296         log_fetch(name, type);
7297
7298         /*
7299          * XXXRTH  use a mempool?
7300          */
7301         fetch = isc_mem_get(res->mctx, sizeof(*fetch));
7302         if (fetch == NULL)
7303                 return (ISC_R_NOMEMORY);
7304
7305         bucketnum = dns_name_fullhash(name, ISC_FALSE) % res->nbuckets;
7306
7307         LOCK(&res->lock);
7308         spillat = res->spillat;
7309         spillatmin = res->spillatmin;
7310         UNLOCK(&res->lock);
7311         LOCK(&res->buckets[bucketnum].lock);
7312
7313         if (res->buckets[bucketnum].exiting) {
7314                 result = ISC_R_SHUTTINGDOWN;
7315                 goto unlock;
7316         }
7317
7318         if ((options & DNS_FETCHOPT_UNSHARED) == 0) {
7319                 for (fctx = ISC_LIST_HEAD(res->buckets[bucketnum].fctxs);
7320                      fctx != NULL;
7321                      fctx = ISC_LIST_NEXT(fctx, link)) {
7322                         if (fctx_match(fctx, name, type, options))
7323                                 break;
7324                 }
7325         }
7326
7327         /*
7328          * Is this a duplicate?
7329          */
7330         if (fctx != NULL && client != NULL) {
7331                 dns_fetchevent_t *fevent;
7332                 for (fevent = ISC_LIST_HEAD(fctx->events);
7333                      fevent != NULL;
7334                      fevent = ISC_LIST_NEXT(fevent, ev_link)) {
7335                         if (fevent->client != NULL && fevent->id == id &&
7336                             isc_sockaddr_equal(fevent->client, client)) {
7337                                 result = DNS_R_DUPLICATE;
7338                                 goto unlock;
7339                         }
7340                         count++;
7341                 }
7342         }
7343         if (count >= spillatmin && spillatmin != 0) {
7344                 INSIST(fctx != NULL);
7345                 if (count >= spillat)
7346                         fctx->spilled = ISC_TRUE;
7347                 if (fctx->spilled) {
7348                         result = DNS_R_DROP;
7349                         goto unlock;
7350                 }
7351         }
7352
7353         /*
7354          * If we didn't have a fetch, would attach to a done fetch, this
7355          * fetch has already cloned its results, or if the fetch has gone
7356          * "idle" (no one was interested in it), we need to start a new
7357          * fetch instead of joining with the existing one.
7358          */
7359         if (fctx == NULL ||
7360             fctx->state == fetchstate_done ||
7361             fctx->cloned ||
7362             ISC_LIST_EMPTY(fctx->events)) {
7363                 fctx = NULL;
7364                 result = fctx_create(res, name, type, domain, nameservers,
7365                                      options, bucketnum, &fctx);
7366                 if (result != ISC_R_SUCCESS)
7367                         goto unlock;
7368                 new_fctx = ISC_TRUE;
7369         }
7370
7371         result = fctx_join(fctx, task, client, id, action, arg,
7372                            rdataset, sigrdataset, fetch);
7373         if (new_fctx) {
7374                 if (result == ISC_R_SUCCESS) {
7375                         /*
7376                          * Launch this fctx.
7377                          */
7378                         event = &fctx->control_event;
7379                         ISC_EVENT_INIT(event, sizeof(*event), 0, NULL,
7380                                        DNS_EVENT_FETCHCONTROL,
7381                                        fctx_start, fctx, NULL,
7382                                        NULL, NULL);
7383                         isc_task_send(res->buckets[bucketnum].task, &event);
7384                 } else {
7385                         /*
7386                          * We don't care about the result of fctx_destroy()
7387                          * since we know we're not exiting.
7388                          */
7389                         (void)fctx_destroy(fctx);
7390                 }
7391         }
7392
7393  unlock:
7394         UNLOCK(&res->buckets[bucketnum].lock);
7395
7396         if (result == ISC_R_SUCCESS) {
7397                 FTRACE("created");
7398                 *fetchp = fetch;
7399         } else
7400                 isc_mem_put(res->mctx, fetch, sizeof(*fetch));
7401
7402         return (result);
7403 }
7404
7405 void
7406 dns_resolver_cancelfetch(dns_fetch_t *fetch) {
7407         fetchctx_t *fctx;
7408         dns_resolver_t *res;
7409         dns_fetchevent_t *event, *next_event;
7410         isc_task_t *etask;
7411
7412         REQUIRE(DNS_FETCH_VALID(fetch));
7413         fctx = fetch->private;
7414         REQUIRE(VALID_FCTX(fctx));
7415         res = fctx->res;
7416
7417         FTRACE("cancelfetch");
7418
7419         LOCK(&res->buckets[fctx->bucketnum].lock);
7420
7421         /*
7422          * Find the completion event for this fetch (as opposed
7423          * to those for other fetches that have joined the same
7424          * fctx) and send it with result = ISC_R_CANCELED.
7425          */
7426         event = NULL;
7427         if (fctx->state != fetchstate_done) {
7428                 for (event = ISC_LIST_HEAD(fctx->events);
7429                      event != NULL;
7430                      event = next_event) {
7431                         next_event = ISC_LIST_NEXT(event, ev_link);
7432                         if (event->fetch == fetch) {
7433                                 ISC_LIST_UNLINK(fctx->events, event, ev_link);
7434                                 break;
7435                         }
7436                 }
7437         }
7438         if (event != NULL) {
7439                 etask = event->ev_sender;
7440                 event->ev_sender = fctx;
7441                 event->result = ISC_R_CANCELED;
7442                 isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event));
7443         }
7444         /*
7445          * The fctx continues running even if no fetches remain;
7446          * the answer is still cached.
7447          */
7448
7449         UNLOCK(&res->buckets[fctx->bucketnum].lock);
7450 }
7451
7452 void
7453 dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
7454         dns_fetch_t *fetch;
7455         dns_resolver_t *res;
7456         dns_fetchevent_t *event, *next_event;
7457         fetchctx_t *fctx;
7458         unsigned int bucketnum;
7459         isc_boolean_t bucket_empty = ISC_FALSE;
7460
7461         REQUIRE(fetchp != NULL);
7462         fetch = *fetchp;
7463         REQUIRE(DNS_FETCH_VALID(fetch));
7464         fctx = fetch->private;
7465         REQUIRE(VALID_FCTX(fctx));
7466         res = fctx->res;
7467
7468         FTRACE("destroyfetch");
7469
7470         bucketnum = fctx->bucketnum;
7471         LOCK(&res->buckets[bucketnum].lock);
7472
7473         /*
7474          * Sanity check: the caller should have gotten its event before
7475          * trying to destroy the fetch.
7476          */
7477         event = NULL;
7478         if (fctx->state != fetchstate_done) {
7479                 for (event = ISC_LIST_HEAD(fctx->events);
7480                      event != NULL;
7481                      event = next_event) {
7482                         next_event = ISC_LIST_NEXT(event, ev_link);
7483                         RUNTIME_CHECK(event->fetch != fetch);
7484                 }
7485         }
7486
7487         INSIST(fctx->references > 0);
7488         fctx->references--;
7489         if (fctx->references == 0) {
7490                 /*
7491                  * No one cares about the result of this fetch anymore.
7492                  */
7493                 if (fctx->pending == 0 && fctx->nqueries == 0 &&
7494                     ISC_LIST_EMPTY(fctx->validators) &&
7495                     SHUTTINGDOWN(fctx)) {
7496                         /*
7497                          * This fctx is already shutdown; we were just
7498                          * waiting for the last reference to go away.
7499                          */
7500                         bucket_empty = fctx_destroy(fctx);
7501                 } else {
7502                         /*
7503                          * Initiate shutdown.
7504                          */
7505                         fctx_shutdown(fctx);
7506                 }
7507         }
7508
7509         UNLOCK(&res->buckets[bucketnum].lock);
7510
7511         isc_mem_put(res->mctx, fetch, sizeof(*fetch));
7512         *fetchp = NULL;
7513
7514         if (bucket_empty)
7515                 empty_bucket(res);
7516 }
7517
7518 void
7519 dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx,
7520                       isc_logcategory_t *category, isc_logmodule_t *module,
7521                       int level, isc_boolean_t duplicateok)
7522 {
7523         fetchctx_t *fctx;
7524         dns_resolver_t *res;
7525         char domainbuf[DNS_NAME_FORMATSIZE];
7526
7527         REQUIRE(DNS_FETCH_VALID(fetch));
7528         fctx = fetch->private;
7529         REQUIRE(VALID_FCTX(fctx));
7530         res = fctx->res;
7531
7532         LOCK(&res->buckets[fctx->bucketnum].lock);
7533
7534         INSIST(fctx->exitline >= 0);
7535         if (!fctx->logged || duplicateok) {
7536                 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
7537                 isc_log_write(lctx, category, module, level,
7538                               "fetch completed at %s:%d for %s in "
7539                               "%" ISC_PRINT_QUADFORMAT "u."
7540                               "%06" ISC_PRINT_QUADFORMAT "u: %s/%s "
7541                               "[domain:%s,referral:%u,restart:%u,qrysent:%u,"
7542                               "timeout:%u,lame:%u,neterr:%u,badresp:%u,"
7543                               "adberr:%u,findfail:%u,valfail:%u]",
7544                               __FILE__, fctx->exitline, fctx->info,
7545                               fctx->duration / 1000000,
7546                               fctx->duration % 1000000,
7547                               isc_result_totext(fctx->result),
7548                               isc_result_totext(fctx->vresult), domainbuf,
7549                               fctx->referrals, fctx->restarts,
7550                               fctx->querysent, fctx->timeouts, fctx->lamecount,
7551                               fctx->neterr, fctx->badresp, fctx->adberr,
7552                               fctx->findfail, fctx->valfail);
7553                 fctx->logged = ISC_TRUE;
7554         }
7555
7556         UNLOCK(&res->buckets[fctx->bucketnum].lock);
7557 }
7558
7559 dns_dispatchmgr_t *
7560 dns_resolver_dispatchmgr(dns_resolver_t *resolver) {
7561         REQUIRE(VALID_RESOLVER(resolver));
7562         return (resolver->dispatchmgr);
7563 }
7564
7565 dns_dispatch_t *
7566 dns_resolver_dispatchv4(dns_resolver_t *resolver) {
7567         REQUIRE(VALID_RESOLVER(resolver));
7568         return (resolver->dispatchv4);
7569 }
7570
7571 dns_dispatch_t *
7572 dns_resolver_dispatchv6(dns_resolver_t *resolver) {
7573         REQUIRE(VALID_RESOLVER(resolver));
7574         return (resolver->dispatchv6);
7575 }
7576
7577 isc_socketmgr_t *
7578 dns_resolver_socketmgr(dns_resolver_t *resolver) {
7579         REQUIRE(VALID_RESOLVER(resolver));
7580         return (resolver->socketmgr);
7581 }
7582
7583 isc_taskmgr_t *
7584 dns_resolver_taskmgr(dns_resolver_t *resolver) {
7585         REQUIRE(VALID_RESOLVER(resolver));
7586         return (resolver->taskmgr);
7587 }
7588
7589 isc_uint32_t
7590 dns_resolver_getlamettl(dns_resolver_t *resolver) {
7591         REQUIRE(VALID_RESOLVER(resolver));
7592         return (resolver->lame_ttl);
7593 }
7594
7595 void
7596 dns_resolver_setlamettl(dns_resolver_t *resolver, isc_uint32_t lame_ttl) {
7597         REQUIRE(VALID_RESOLVER(resolver));
7598         resolver->lame_ttl = lame_ttl;
7599 }
7600
7601 unsigned int
7602 dns_resolver_nrunning(dns_resolver_t *resolver) {
7603         unsigned int n;
7604         LOCK(&resolver->nlock);
7605         n = resolver->nfctx;
7606         UNLOCK(&resolver->nlock);
7607         return (n);
7608 }
7609
7610 isc_result_t
7611 dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt,
7612                           dns_name_t *name, in_port_t port) {
7613         alternate_t *a;
7614         isc_result_t result;
7615
7616         REQUIRE(VALID_RESOLVER(resolver));
7617         REQUIRE(!resolver->frozen);
7618         REQUIRE((alt == NULL) ^ (name == NULL));
7619
7620         a = isc_mem_get(resolver->mctx, sizeof(*a));
7621         if (a == NULL)
7622                 return (ISC_R_NOMEMORY);
7623         if (alt != NULL) {
7624                 a->isaddress = ISC_TRUE;
7625                 a->_u.addr = *alt;
7626         } else {
7627                 a->isaddress = ISC_FALSE;
7628                 a->_u._n.port = port;
7629                 dns_name_init(&a->_u._n.name, NULL);
7630                 result = dns_name_dup(name, resolver->mctx, &a->_u._n.name);
7631                 if (result != ISC_R_SUCCESS) {
7632                         isc_mem_put(resolver->mctx, a, sizeof(*a));
7633                         return (result);
7634                 }
7635         }
7636         ISC_LINK_INIT(a, link);
7637         ISC_LIST_APPEND(resolver->alternates, a, link);
7638
7639         return (ISC_R_SUCCESS);
7640 }
7641
7642 void
7643 dns_resolver_setudpsize(dns_resolver_t *resolver, isc_uint16_t udpsize) {
7644         REQUIRE(VALID_RESOLVER(resolver));
7645         resolver->udpsize = udpsize;
7646 }
7647
7648 isc_uint16_t
7649 dns_resolver_getudpsize(dns_resolver_t *resolver) {
7650         REQUIRE(VALID_RESOLVER(resolver));
7651         return (resolver->udpsize);
7652 }
7653
7654 static void
7655 free_algorithm(void *node, void *arg) {
7656         unsigned char *algorithms = node;
7657         isc_mem_t *mctx = arg;
7658
7659         isc_mem_put(mctx, algorithms, *algorithms);
7660 }
7661
7662 void
7663 dns_resolver_reset_algorithms(dns_resolver_t *resolver) {
7664
7665         REQUIRE(VALID_RESOLVER(resolver));
7666
7667 #if USE_ALGLOCK
7668         RWLOCK(&resolver->alglock, isc_rwlocktype_write);
7669 #endif
7670         if (resolver->algorithms != NULL)
7671                 dns_rbt_destroy(&resolver->algorithms);
7672 #if USE_ALGLOCK
7673         RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
7674 #endif
7675 }
7676
7677 isc_result_t
7678 dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
7679                                unsigned int alg)
7680 {
7681         unsigned int len, mask;
7682         unsigned char *new;
7683         unsigned char *algorithms;
7684         isc_result_t result;
7685         dns_rbtnode_t *node = NULL;
7686
7687         REQUIRE(VALID_RESOLVER(resolver));
7688         if (alg > 255)
7689                 return (ISC_R_RANGE);
7690
7691 #if USE_ALGLOCK
7692         RWLOCK(&resolver->alglock, isc_rwlocktype_write);
7693 #endif
7694         if (resolver->algorithms == NULL) {
7695                 result = dns_rbt_create(resolver->mctx, free_algorithm,
7696                                         resolver->mctx, &resolver->algorithms);
7697                 if (result != ISC_R_SUCCESS)
7698                         goto cleanup;
7699         }
7700
7701         len = alg/8 + 2;
7702         mask = 1 << (alg%8);
7703
7704         result = dns_rbt_addnode(resolver->algorithms, name, &node);
7705
7706         if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
7707                 algorithms = node->data;
7708                 if (algorithms == NULL || len > *algorithms) {
7709                         new = isc_mem_get(resolver->mctx, len);
7710                         if (new == NULL) {
7711                                 result = ISC_R_NOMEMORY;
7712                                 goto cleanup;
7713                         }
7714                         memset(new, 0, len);
7715                         if (algorithms != NULL)
7716                                 memcpy(new, algorithms, *algorithms);
7717                         new[len-1] |= mask;
7718                         *new = len;
7719                         node->data = new;
7720                         if (algorithms != NULL)
7721                                 isc_mem_put(resolver->mctx, algorithms,
7722                                             *algorithms);
7723                 } else
7724                         algorithms[len-1] |= mask;
7725         }
7726         result = ISC_R_SUCCESS;
7727  cleanup:
7728 #if USE_ALGLOCK
7729         RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
7730 #endif
7731         return (result);
7732 }
7733
7734 isc_boolean_t
7735 dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
7736                                  unsigned int alg)
7737 {
7738         unsigned int len, mask;
7739         unsigned char *algorithms;
7740         void *data = NULL;
7741         isc_result_t result;
7742         isc_boolean_t found = ISC_FALSE;
7743
7744         REQUIRE(VALID_RESOLVER(resolver));
7745
7746 #if USE_ALGLOCK
7747         RWLOCK(&resolver->alglock, isc_rwlocktype_read);
7748 #endif
7749         if (resolver->algorithms == NULL)
7750                 goto unlock;
7751         result = dns_rbt_findname(resolver->algorithms, name, 0, NULL, &data);
7752         if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
7753                 len = alg/8 + 2;
7754                 mask = 1 << (alg%8);
7755                 algorithms = data;
7756                 if (len <= *algorithms && (algorithms[len-1] & mask) != 0)
7757                         found = ISC_TRUE;
7758         }
7759  unlock:
7760 #if USE_ALGLOCK
7761         RWUNLOCK(&resolver->alglock, isc_rwlocktype_read);
7762 #endif
7763         if (found)
7764                 return (ISC_FALSE);
7765         return (dst_algorithm_supported(alg));
7766 }
7767
7768 isc_boolean_t
7769 dns_resolver_digest_supported(dns_resolver_t *resolver, unsigned int digest) {
7770
7771         UNUSED(resolver);
7772         return (dns_ds_digest_supported(digest));
7773 }
7774
7775 void
7776 dns_resolver_resetmustbesecure(dns_resolver_t *resolver) {
7777
7778         REQUIRE(VALID_RESOLVER(resolver));
7779
7780 #if USE_MBSLOCK
7781         RWLOCK(&resolver->mbslock, isc_rwlocktype_write);
7782 #endif
7783         if (resolver->mustbesecure != NULL)
7784                 dns_rbt_destroy(&resolver->mustbesecure);
7785 #if USE_MBSLOCK
7786         RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write);
7787 #endif
7788 }
7789
7790 static isc_boolean_t yes = ISC_TRUE, no = ISC_FALSE;
7791
7792 isc_result_t
7793 dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name,
7794                              isc_boolean_t value)
7795 {
7796         isc_result_t result;
7797
7798         REQUIRE(VALID_RESOLVER(resolver));
7799
7800 #if USE_MBSLOCK
7801         RWLOCK(&resolver->mbslock, isc_rwlocktype_write);
7802 #endif
7803         if (resolver->mustbesecure == NULL) {
7804                 result = dns_rbt_create(resolver->mctx, NULL, NULL,
7805                                         &resolver->mustbesecure);
7806                 if (result != ISC_R_SUCCESS)
7807                         goto cleanup;
7808         }
7809         result = dns_rbt_addname(resolver->mustbesecure, name,
7810                                  value ? &yes : &no);
7811  cleanup:
7812 #if USE_MBSLOCK
7813         RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write);
7814 #endif
7815         return (result);
7816 }
7817
7818 isc_boolean_t
7819 dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name) {
7820         void *data = NULL;
7821         isc_boolean_t value = ISC_FALSE;
7822         isc_result_t result;
7823
7824         REQUIRE(VALID_RESOLVER(resolver));
7825
7826 #if USE_MBSLOCK
7827         RWLOCK(&resolver->mbslock, isc_rwlocktype_read);
7828 #endif
7829         if (resolver->mustbesecure == NULL)
7830                 goto unlock;
7831         result = dns_rbt_findname(resolver->mustbesecure, name, 0, NULL, &data);
7832         if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
7833                 value = *(isc_boolean_t*)data;
7834  unlock:
7835 #if USE_MBSLOCK
7836         RWUNLOCK(&resolver->mbslock, isc_rwlocktype_read);
7837 #endif
7838         return (value);
7839 }
7840
7841 void
7842 dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur,
7843                                 isc_uint32_t *min, isc_uint32_t *max)
7844 {
7845         REQUIRE(VALID_RESOLVER(resolver));
7846
7847         LOCK(&resolver->lock);
7848         if (cur != NULL)
7849                 *cur = resolver->spillat;
7850         if (min != NULL)
7851                 *min = resolver->spillatmin;
7852         if (max != NULL)
7853                 *max = resolver->spillatmax;
7854         UNLOCK(&resolver->lock);
7855 }
7856
7857 void
7858 dns_resolver_setclientsperquery(dns_resolver_t *resolver, isc_uint32_t min,
7859                                 isc_uint32_t max)
7860 {
7861         REQUIRE(VALID_RESOLVER(resolver));
7862
7863         LOCK(&resolver->lock);
7864         resolver->spillatmin = resolver->spillat = min;
7865         resolver->spillatmax = max;
7866         UNLOCK(&resolver->lock);
7867 }
7868
7869 isc_boolean_t
7870 dns_resolver_getzeronosoattl(dns_resolver_t *resolver) {
7871         REQUIRE(VALID_RESOLVER(resolver));
7872
7873         return (resolver->zero_no_soa_ttl);
7874 }
7875
7876 void
7877 dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state) {
7878         REQUIRE(VALID_RESOLVER(resolver));
7879
7880         resolver->zero_no_soa_ttl = state;
7881 }
7882
7883 unsigned int
7884 dns_resolver_getoptions(dns_resolver_t *resolver) {
7885         REQUIRE(VALID_RESOLVER(resolver));
7886
7887         return (resolver->options);
7888 }