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