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