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