2 * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
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.
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.
24 #include <isc/counter.h>
25 #include <isc/platform.h>
26 #include <isc/print.h>
27 #include <isc/string.h>
28 #include <isc/random.h>
30 #include <isc/stats.h>
31 #include <isc/timer.h>
36 #include <dns/cache.h>
38 #include <dns/dispatch.h>
40 #include <dns/events.h>
41 #include <dns/forward.h>
42 #include <dns/keytable.h>
44 #include <dns/message.h>
45 #include <dns/ncache.h>
46 #include <dns/opcode.h>
49 #include <dns/rcode.h>
50 #include <dns/rdata.h>
51 #include <dns/rdataclass.h>
52 #include <dns/rdatalist.h>
53 #include <dns/rdataset.h>
54 #include <dns/rdatastruct.h>
55 #include <dns/rdatatype.h>
56 #include <dns/resolver.h>
57 #include <dns/result.h>
58 #include <dns/rootns.h>
59 #include <dns/stats.h>
61 #include <dns/validator.h>
63 #define DNS_RESOLVER_TRACE
64 #ifdef DNS_RESOLVER_TRACE
65 #define RTRACE(m) isc_log_write(dns_lctx, \
66 DNS_LOGCATEGORY_RESOLVER, \
67 DNS_LOGMODULE_RESOLVER, \
69 "res %p: %s", res, (m))
70 #define RRTRACE(r, m) isc_log_write(dns_lctx, \
71 DNS_LOGCATEGORY_RESOLVER, \
72 DNS_LOGMODULE_RESOLVER, \
74 "res %p: %s", (r), (m))
75 #define FCTXTRACE(m) isc_log_write(dns_lctx, \
76 DNS_LOGCATEGORY_RESOLVER, \
77 DNS_LOGMODULE_RESOLVER, \
79 "fctx %p(%s'): %s", fctx, fctx->info, (m))
80 #define FCTXTRACE2(m1, m2) \
81 isc_log_write(dns_lctx, \
82 DNS_LOGCATEGORY_RESOLVER, \
83 DNS_LOGMODULE_RESOLVER, \
85 "fctx %p(%s): %s %s", \
86 fctx, fctx->info, (m1), (m2))
87 #define FTRACE(m) isc_log_write(dns_lctx, \
88 DNS_LOGCATEGORY_RESOLVER, \
89 DNS_LOGMODULE_RESOLVER, \
91 "fetch %p (fctx %p(%s)): %s", \
92 fetch, fetch->private, \
93 fetch->private->info, (m))
94 #define QTRACE(m) isc_log_write(dns_lctx, \
95 DNS_LOGCATEGORY_RESOLVER, \
96 DNS_LOGMODULE_RESOLVER, \
98 "resquery %p (fctx %p(%s)): %s", \
100 query->fctx->info, (m))
103 #define RRTRACE(r, m)
109 #ifndef DEFAULT_QUERY_TIMEOUT
110 #define DEFAULT_QUERY_TIMEOUT 30 /* The default time in seconds for the whole query to live. */
113 #ifndef MAXIMUM_QUERY_TIMEOUT
114 #define MAXIMUM_QUERY_TIMEOUT 30 /* The maximum time in seconds for the whole query to live. */
117 /* The default maximum number of recursions to follow before giving up. */
118 #ifndef DEFAULT_RECURSION_DEPTH
119 #define DEFAULT_RECURSION_DEPTH 7
122 /* The default maximum number of iterative queries to allow before giving up. */
123 #ifndef DEFAULT_MAX_QUERIES
124 #define DEFAULT_MAX_QUERIES 50
128 * Maximum EDNS0 input packet size.
130 #define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */
133 * This defines the maximum number of timeouts we will permit before we
134 * disable EDNS0 on the query.
136 #define MAX_EDNS0_TIMEOUTS 3
138 typedef struct fetchctx fetchctx_t;
140 typedef struct query {
141 /* Locked by task event serialization. */
145 dns_dispatchmgr_t * dispatchmgr;
146 dns_dispatch_t * dispatch;
147 isc_boolean_t exclusivesocket;
148 dns_adbaddrinfo_t * addrinfo;
149 isc_socket_t * tcpsocket;
152 dns_dispentry_t * dispentry;
153 ISC_LINK(struct query) link;
156 dns_tsigkey_t *tsigkey;
157 unsigned int options;
158 unsigned int attributes;
160 unsigned int connects;
161 unsigned char data[512];
164 #define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!')
165 #define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC)
167 #define RESQUERY_ATTR_CANCELED 0x02
169 #define RESQUERY_CONNECTING(q) ((q)->connects > 0)
170 #define RESQUERY_CANCELED(q) (((q)->attributes & \
171 RESQUERY_ATTR_CANCELED) != 0)
172 #define RESQUERY_SENDING(q) ((q)->sends > 0)
175 fetchstate_init = 0, /*%< Start event has not run yet. */
177 fetchstate_done /*%< FETCHDONE events posted. */
181 badns_unreachable = 0,
189 dns_resolver_t * res;
191 dns_rdatatype_t type;
192 unsigned int options;
193 unsigned int bucketnum;
197 /*% Locked by appropriate bucket lock. */
199 isc_boolean_t want_shutdown;
200 isc_boolean_t cloned;
201 isc_boolean_t spilled;
202 unsigned int references;
203 isc_event_t control_event;
204 ISC_LINK(struct fetchctx) link;
205 ISC_LIST(dns_fetchevent_t) events;
206 /*% Locked by task event serialization. */
208 dns_rdataset_t nameservers;
209 unsigned int attributes;
212 isc_interval_t interval;
213 dns_message_t * qmessage;
214 dns_message_t * rmessage;
215 ISC_LIST(resquery_t) queries;
216 dns_adbfindlist_t finds;
217 dns_adbfind_t * find;
218 dns_adbfindlist_t altfinds;
219 dns_adbfind_t * altfind;
220 dns_adbaddrinfolist_t forwaddrs;
221 dns_adbaddrinfolist_t altaddrs;
222 isc_sockaddrlist_t forwarders;
223 dns_fwdpolicy_t fwdpolicy;
224 isc_sockaddrlist_t bad;
225 isc_sockaddrlist_t edns;
226 isc_sockaddrlist_t edns512;
227 isc_sockaddrlist_t bad_edns;
228 dns_validator_t * validator;
229 ISC_LIST(dns_validator_t) validators;
232 isc_boolean_t ns_ttl_ok;
237 * The number of events we're waiting for.
239 unsigned int pending;
242 * The number of times we've "restarted" the current
243 * nameserver set. This acts as a failsafe to prevent
244 * us from pounding constantly on a particular set of
245 * servers that, for whatever reason, are not giving
246 * us useful responses, but are responding in such a
247 * way that they are not marked "bad".
249 unsigned int restarts;
252 * The number of timeouts that have occurred since we
253 * last successfully received a response packet. This
254 * is used for EDNS0 black hole detection.
256 unsigned int timeouts;
259 * Look aside state for DS lookups.
262 dns_fetch_t * nsfetch;
263 dns_rdataset_t nsrrset;
266 * Number of queries that reference this context.
268 unsigned int nqueries;
271 * The reason to print when logging a successful
272 * response to a query.
277 * Random numbers to use for mixing up server addresses.
279 isc_uint32_t rand_buf;
280 isc_uint32_t rand_bits;
283 * Fetch-local statistics for detailed logging.
285 isc_result_t result; /*%< fetch result */
286 isc_result_t vresult; /*%< validation result */
289 isc_uint64_t duration;
290 isc_boolean_t logged;
291 unsigned int querysent;
292 unsigned int referrals;
293 unsigned int lamecount;
295 unsigned int badresp;
297 unsigned int findfail;
298 unsigned int valfail;
299 isc_boolean_t timeout;
300 dns_adbaddrinfo_t *addrinfo;
301 isc_sockaddr_t *client;
305 #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
306 #define VALID_FCTX(fctx) ISC_MAGIC_VALID(fctx, FCTX_MAGIC)
308 #define FCTX_ATTR_HAVEANSWER 0x0001
309 #define FCTX_ATTR_GLUING 0x0002
310 #define FCTX_ATTR_ADDRWAIT 0x0004
311 #define FCTX_ATTR_SHUTTINGDOWN 0x0008
312 #define FCTX_ATTR_WANTCACHE 0x0010
313 #define FCTX_ATTR_WANTNCACHE 0x0020
314 #define FCTX_ATTR_NEEDEDNS0 0x0040
315 #define FCTX_ATTR_TRIEDFIND 0x0080
316 #define FCTX_ATTR_TRIEDALT 0x0100
318 #define HAVE_ANSWER(f) (((f)->attributes & FCTX_ATTR_HAVEANSWER) != \
320 #define GLUING(f) (((f)->attributes & FCTX_ATTR_GLUING) != \
322 #define ADDRWAIT(f) (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \
324 #define SHUTTINGDOWN(f) (((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \
326 #define WANTCACHE(f) (((f)->attributes & FCTX_ATTR_WANTCACHE) != 0)
327 #define WANTNCACHE(f) (((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0)
328 #define NEEDEDNS0(f) (((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0)
329 #define TRIEDFIND(f) (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0)
330 #define TRIEDALT(f) (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0)
333 dns_adbaddrinfo_t * addrinfo;
339 fetchctx_t * private;
342 #define DNS_FETCH_MAGIC ISC_MAGIC('F', 't', 'c', 'h')
343 #define DNS_FETCH_VALID(fetch) ISC_MAGIC_VALID(fetch, DNS_FETCH_MAGIC)
345 typedef struct fctxbucket {
348 ISC_LIST(fetchctx_t) fctxs;
349 isc_boolean_t exiting;
353 typedef struct alternate {
354 isc_boolean_t isaddress;
362 ISC_LINK(struct alternate) link;
365 typedef struct dns_badcache dns_badcache_t;
366 struct dns_badcache {
367 dns_badcache_t * next;
368 dns_rdatatype_t type;
370 unsigned int hashval;
373 #define DNS_BADCACHE_SIZE 1021
374 #define DNS_BADCACHE_TTL(fctx) \
375 (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30)
377 struct dns_resolver {
383 isc_mutex_t primelock;
384 dns_rdataclass_t rdclass;
385 isc_socketmgr_t * socketmgr;
386 isc_timermgr_t * timermgr;
387 isc_taskmgr_t * taskmgr;
389 isc_boolean_t frozen;
390 unsigned int options;
391 dns_dispatchmgr_t * dispatchmgr;
392 dns_dispatch_t * dispatchv4;
393 isc_boolean_t exclusivev4;
394 dns_dispatch_t * dispatchv6;
395 isc_boolean_t exclusivev6;
397 unsigned int nbuckets;
398 fctxbucket_t * buckets;
399 isc_uint32_t lame_ttl;
400 ISC_LIST(alternate_t) alternates;
401 isc_uint16_t udpsize;
403 isc_rwlock_t alglock;
405 dns_rbt_t * algorithms;
407 isc_rwlock_t mbslock;
409 dns_rbt_t * mustbesecure;
410 unsigned int spillatmax;
411 unsigned int spillatmin;
412 isc_timer_t * spillattimer;
413 isc_boolean_t zero_no_soa_ttl;
414 unsigned int query_timeout;
415 unsigned int maxdepth;
416 unsigned int maxqueries;
418 /* Locked by lock. */
419 unsigned int references;
420 isc_boolean_t exiting;
421 isc_eventlist_t whenshutdown;
422 unsigned int activebuckets;
423 isc_boolean_t priming;
424 unsigned int spillat; /* clients-per-query */
425 unsigned int nextdisp;
428 dns_badcache_t ** badcache;
429 unsigned int badcount;
430 unsigned int badhash;
431 unsigned int badsweep;
433 /* Locked by primelock. */
434 dns_fetch_t * primefetch;
435 /* Locked by nlock. */
439 #define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!')
440 #define VALID_RESOLVER(res) ISC_MAGIC_VALID(res, RES_MAGIC)
443 * Private addrinfo flags. These must not conflict with DNS_FETCHOPT_NOEDNS0,
444 * which we also use as an addrinfo flag.
446 #define FCTX_ADDRINFO_MARK 0x0001
447 #define FCTX_ADDRINFO_FORWARDER 0x1000
448 #define FCTX_ADDRINFO_TRIED 0x2000
449 #define UNMARKED(a) (((a)->flags & FCTX_ADDRINFO_MARK) \
451 #define ISFORWARDER(a) (((a)->flags & \
452 FCTX_ADDRINFO_FORWARDER) != 0)
453 #define TRIED(a) (((a)->flags & \
454 FCTX_ADDRINFO_TRIED) != 0)
456 #define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
457 #define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
459 static void destroy(dns_resolver_t *res);
460 static void empty_bucket(dns_resolver_t *res);
461 static isc_result_t resquery_send(resquery_t *query);
462 static void resquery_response(isc_task_t *task, isc_event_t *event);
463 static void resquery_connected(isc_task_t *task, isc_event_t *event);
464 static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying,
465 isc_boolean_t badcache);
466 static void fctx_destroy(fetchctx_t *fctx);
467 static isc_boolean_t fctx_unlink(fetchctx_t *fctx);
468 static isc_result_t ncache_adderesult(dns_message_t *message,
469 dns_db_t *cache, dns_dbnode_t *node,
470 dns_rdatatype_t covers,
471 isc_stdtime_t now, dns_ttl_t maxttl,
472 isc_boolean_t optout,
473 dns_rdataset_t *ardataset,
474 isc_result_t *eresultp);
475 static void validated(isc_task_t *task, isc_event_t *event);
476 static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked);
477 static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
478 isc_result_t reason, badnstype_t badtype);
481 * Increment resolver-related statistics counters.
484 inc_stats(dns_resolver_t *res, isc_statscounter_t counter) {
485 if (res->view->resstats != NULL)
486 isc_stats_increment(res->view->resstats, counter);
490 valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
491 dns_rdatatype_t type, dns_rdataset_t *rdataset,
492 dns_rdataset_t *sigrdataset, unsigned int valoptions,
495 dns_validator_t *validator = NULL;
496 dns_valarg_t *valarg;
499 valarg = isc_mem_get(fctx->mctx, sizeof(*valarg));
501 return (ISC_R_NOMEMORY);
504 valarg->addrinfo = addrinfo;
506 if (!ISC_LIST_EMPTY(fctx->validators))
507 INSIST((valoptions & DNS_VALIDATOR_DEFER) != 0);
509 result = dns_validator_create(fctx->res->view, name, type, rdataset,
510 sigrdataset, fctx->rmessage,
511 valoptions, task, validated, valarg,
513 if (result == ISC_R_SUCCESS) {
514 inc_stats(fctx->res, dns_resstatscounter_val);
515 if ((valoptions & DNS_VALIDATOR_DEFER) == 0) {
516 INSIST(fctx->validator == NULL);
517 fctx->validator = validator;
519 ISC_LIST_APPEND(fctx->validators, validator, link);
521 isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
526 rrsig_fromchildzone(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
527 dns_namereln_t namereln;
528 dns_rdata_rrsig_t rrsig;
529 dns_rdata_t rdata = DNS_RDATA_INIT;
534 for (result = dns_rdataset_first(rdataset);
535 result == ISC_R_SUCCESS;
536 result = dns_rdataset_next(rdataset)) {
537 dns_rdataset_current(rdataset, &rdata);
538 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
539 RUNTIME_CHECK(result == ISC_R_SUCCESS);
540 namereln = dns_name_fullcompare(&rrsig.signer, &fctx->domain,
542 if (namereln == dns_namereln_subdomain)
544 dns_rdata_reset(&rdata);
550 fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
552 dns_name_t *domain = &fctx->domain;
553 dns_rdataset_t *rdataset;
554 dns_rdatatype_t type;
556 isc_boolean_t keep_auth = ISC_FALSE;
558 if (message->rcode == dns_rcode_nxdomain)
562 * A DS RRset can appear anywhere in a zone, even for a delegation-only
563 * zone. So a response to an explicit query for this type should be
564 * excluded from delegation-only fixup.
566 * SOA, NS, and DNSKEY can only exist at a zone apex, so a postive
567 * response to a query for these types can never violate the
568 * delegation-only assumption: if the query name is below a
569 * zone cut, the response should normally be a referral, which should
570 * be accepted; if the query name is below a zone cut but the server
571 * happens to have authority for the zone of the query name, the
572 * response is a (non-referral) answer. But this does not violate
573 * delegation-only because the query name must be in a different zone
574 * due to the "apex-only" nature of these types. Note that if the
575 * remote server happens to have authority for a child zone of a
576 * delegation-only zone, we may still incorrectly "fix" the response
577 * with NXDOMAIN for queries for other types. Unfortunately it's
578 * generally impossible to differentiate this case from violation of
579 * the delegation-only assumption. Once the resolver learns the
580 * correct zone cut, possibly via a separate query for an "apex-only"
581 * type, queries for other types will be resolved correctly.
583 * A query for type ANY will be accepted if it hits an exceptional
584 * type above in the answer section as it should be from a child
587 * Also accept answers with RRSIG records from the child zone.
588 * Direct queries for RRSIG records should not be answered from
592 if (message->counts[DNS_SECTION_ANSWER] != 0 &&
593 (fctx->type == dns_rdatatype_ns ||
594 fctx->type == dns_rdatatype_ds ||
595 fctx->type == dns_rdatatype_soa ||
596 fctx->type == dns_rdatatype_any ||
597 fctx->type == dns_rdatatype_rrsig ||
598 fctx->type == dns_rdatatype_dnskey)) {
599 result = dns_message_firstname(message, DNS_SECTION_ANSWER);
600 while (result == ISC_R_SUCCESS) {
602 dns_message_currentname(message, DNS_SECTION_ANSWER,
604 for (rdataset = ISC_LIST_HEAD(name->list);
606 rdataset = ISC_LIST_NEXT(rdataset, link)) {
607 if (!dns_name_equal(name, &fctx->name))
609 type = rdataset->type;
613 if (type == dns_rdatatype_rrsig &&
614 rrsig_fromchildzone(fctx, rdataset))
617 * Direct query for apex records or DS.
619 if (fctx->type == type &&
620 (type == dns_rdatatype_ds ||
621 type == dns_rdatatype_ns ||
622 type == dns_rdatatype_soa ||
623 type == dns_rdatatype_dnskey))
626 * Indirect query for apex records or DS.
628 if (fctx->type == dns_rdatatype_any &&
629 (type == dns_rdatatype_ns ||
630 type == dns_rdatatype_ds ||
631 type == dns_rdatatype_soa ||
632 type == dns_rdatatype_dnskey))
635 result = dns_message_nextname(message,
641 * A NODATA response to a DS query?
643 if (fctx->type == dns_rdatatype_ds &&
644 message->counts[DNS_SECTION_ANSWER] == 0)
647 /* Look for referral or indication of answer from child zone? */
648 if (message->counts[DNS_SECTION_AUTHORITY] == 0)
651 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
652 while (result == ISC_R_SUCCESS) {
654 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
655 for (rdataset = ISC_LIST_HEAD(name->list);
657 rdataset = ISC_LIST_NEXT(rdataset, link)) {
658 type = rdataset->type;
659 if (type == dns_rdatatype_soa &&
660 dns_name_equal(name, domain))
661 keep_auth = ISC_TRUE;
663 if (type != dns_rdatatype_ns &&
664 type != dns_rdatatype_soa &&
665 type != dns_rdatatype_rrsig)
668 if (type == dns_rdatatype_rrsig) {
669 if (rrsig_fromchildzone(fctx, rdataset))
675 /* NS or SOA records. */
676 if (dns_name_equal(name, domain)) {
678 * If a query for ANY causes a negative
679 * response, we can be sure that this is
680 * an empty node. For other type of queries
681 * we cannot differentiate an empty node
682 * from a node that just doesn't have that
683 * type of record. We only accept the former
686 if (message->counts[DNS_SECTION_ANSWER] == 0 &&
687 fctx->type == dns_rdatatype_any)
689 } else if (dns_name_issubdomain(name, domain)) {
690 /* Referral or answer from child zone. */
694 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
698 message->rcode = dns_rcode_nxdomain;
699 message->counts[DNS_SECTION_ANSWER] = 0;
701 message->counts[DNS_SECTION_AUTHORITY] = 0;
702 message->counts[DNS_SECTION_ADDITIONAL] = 0;
706 static inline isc_result_t
707 fctx_starttimer(fetchctx_t *fctx) {
709 * Start the lifetime timer for fctx.
711 * This is also used for stopping the idle timer; in that
712 * case we must purge events already posted to ensure that
713 * no further idle events are delivered.
715 return (isc_timer_reset(fctx->timer, isc_timertype_once,
716 &fctx->expires, NULL, ISC_TRUE));
720 fctx_stoptimer(fetchctx_t *fctx) {
724 * We don't return a result if resetting the timer to inactive fails
725 * since there's nothing to be done about it. Resetting to inactive
726 * should never fail anyway, since the code as currently written
727 * cannot fail in that case.
729 result = isc_timer_reset(fctx->timer, isc_timertype_inactive,
730 NULL, NULL, ISC_TRUE);
731 if (result != ISC_R_SUCCESS) {
732 UNEXPECTED_ERROR(__FILE__, __LINE__,
733 "isc_timer_reset(): %s",
734 isc_result_totext(result));
739 static inline isc_result_t
740 fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) {
742 * Start the idle timer for fctx. The lifetime timer continues
745 return (isc_timer_reset(fctx->timer, isc_timertype_once,
746 &fctx->expires, interval, ISC_FALSE));
750 * Stopping the idle timer is equivalent to calling fctx_starttimer(), but
751 * we use fctx_stopidletimer for readability in the code below.
753 #define fctx_stopidletimer fctx_starttimer
757 resquery_destroy(resquery_t **queryp) {
760 REQUIRE(queryp != NULL);
762 REQUIRE(!ISC_LINK_LINKED(query, link));
764 INSIST(query->tcpsocket == NULL);
766 query->fctx->nqueries--;
767 if (SHUTTINGDOWN(query->fctx)) {
768 dns_resolver_t *res = query->fctx->res;
769 if (maybe_destroy(query->fctx, ISC_FALSE))
773 isc_mem_put(query->mctx, query, sizeof(*query));
778 fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
779 isc_time_t *finish, isc_boolean_t no_response)
783 unsigned int rtt, rttms;
786 dns_adbaddrinfo_t *addrinfo;
787 isc_socket_t *socket;
792 FCTXTRACE("cancelquery");
794 REQUIRE(!RESQUERY_CANCELED(query));
796 query->attributes |= RESQUERY_ATTR_CANCELED;
799 * Should we update the RTT?
801 if (finish != NULL || no_response) {
802 if (finish != NULL) {
804 * We have both the start and finish times for this
805 * packet, so we can compute a real RTT.
807 rtt = (unsigned int)isc_time_microdiff(finish,
809 factor = DNS_ADB_RTTADJDEFAULT;
812 if (rttms < DNS_RESOLVER_QRYRTTCLASS0) {
814 dns_resstatscounter_queryrtt0);
815 } else if (rttms < DNS_RESOLVER_QRYRTTCLASS1) {
817 dns_resstatscounter_queryrtt1);
818 } else if (rttms < DNS_RESOLVER_QRYRTTCLASS2) {
820 dns_resstatscounter_queryrtt2);
821 } else if (rttms < DNS_RESOLVER_QRYRTTCLASS3) {
823 dns_resstatscounter_queryrtt3);
824 } else if (rttms < DNS_RESOLVER_QRYRTTCLASS4) {
826 dns_resstatscounter_queryrtt4);
829 dns_resstatscounter_queryrtt5);
833 * We don't have an RTT for this query. Maybe the
834 * packet was lost, or maybe this server is very
835 * slow. We don't know. Increase the RTT.
838 rtt = query->addrinfo->srtt + 200000;
842 * Replace the current RTT with our value.
844 factor = DNS_ADB_RTTADJREPLACE;
846 dns_adb_adjustsrtt(fctx->adb, query->addrinfo, rtt, factor);
849 /* Remember that the server has been tried. */
850 if (!TRIED(query->addrinfo)) {
851 dns_adb_changeflags(fctx->adb, query->addrinfo,
852 FCTX_ADDRINFO_TRIED, FCTX_ADDRINFO_TRIED);
856 * Age RTTs of servers not tried.
858 factor = DNS_ADB_RTTADJAGE;
860 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
862 addrinfo = ISC_LIST_NEXT(addrinfo, publink))
863 if (UNMARKED(addrinfo))
864 dns_adb_adjustsrtt(fctx->adb, addrinfo,
867 if (finish != NULL && TRIEDFIND(fctx))
868 for (find = ISC_LIST_HEAD(fctx->finds);
870 find = ISC_LIST_NEXT(find, publink))
871 for (addrinfo = ISC_LIST_HEAD(find->list);
873 addrinfo = ISC_LIST_NEXT(addrinfo, publink))
874 if (UNMARKED(addrinfo))
875 dns_adb_adjustsrtt(fctx->adb, addrinfo,
878 if (finish != NULL && TRIEDALT(fctx)) {
879 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
881 addrinfo = ISC_LIST_NEXT(addrinfo, publink))
882 if (UNMARKED(addrinfo))
883 dns_adb_adjustsrtt(fctx->adb, addrinfo,
885 for (find = ISC_LIST_HEAD(fctx->altfinds);
887 find = ISC_LIST_NEXT(find, publink))
888 for (addrinfo = ISC_LIST_HEAD(find->list);
890 addrinfo = ISC_LIST_NEXT(addrinfo, publink))
891 if (UNMARKED(addrinfo))
892 dns_adb_adjustsrtt(fctx->adb, addrinfo,
897 * Check for any outstanding socket events. If they exist, cancel
898 * them and let the event handlers finish the cleanup. The resolver
899 * only needs to worry about managing the connect and send events;
900 * the dispatcher manages the recv events.
902 if (RESQUERY_CONNECTING(query)) {
904 * Cancel the connect.
906 if (query->tcpsocket != NULL) {
907 isc_socket_cancel(query->tcpsocket, NULL,
908 ISC_SOCKCANCEL_CONNECT);
909 } else if (query->dispentry != NULL) {
910 INSIST(query->exclusivesocket);
911 socket = dns_dispatch_getentrysocket(query->dispentry);
913 isc_socket_cancel(socket, NULL,
914 ISC_SOCKCANCEL_CONNECT);
916 } else if (RESQUERY_SENDING(query)) {
918 * Cancel the pending send.
920 if (query->exclusivesocket && query->dispentry != NULL)
921 socket = dns_dispatch_getentrysocket(query->dispentry);
923 socket = dns_dispatch_getsocket(query->dispatch);
925 isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND);
928 if (query->dispentry != NULL)
929 dns_dispatch_removeresponse(&query->dispentry, deventp);
931 ISC_LIST_UNLINK(fctx->queries, query, link);
933 if (query->tsig != NULL)
934 isc_buffer_free(&query->tsig);
936 if (query->tsigkey != NULL)
937 dns_tsigkey_detach(&query->tsigkey);
939 if (query->dispatch != NULL)
940 dns_dispatch_detach(&query->dispatch);
942 if (! (RESQUERY_CONNECTING(query) || RESQUERY_SENDING(query)))
944 * It's safe to destroy the query now.
946 resquery_destroy(&query);
950 fctx_cancelqueries(fetchctx_t *fctx, isc_boolean_t no_response) {
951 resquery_t *query, *next_query;
953 FCTXTRACE("cancelqueries");
955 for (query = ISC_LIST_HEAD(fctx->queries);
957 query = next_query) {
958 next_query = ISC_LIST_NEXT(query, link);
959 fctx_cancelquery(&query, NULL, NULL, no_response);
964 fctx_cleanupfinds(fetchctx_t *fctx) {
965 dns_adbfind_t *find, *next_find;
967 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
969 for (find = ISC_LIST_HEAD(fctx->finds);
972 next_find = ISC_LIST_NEXT(find, publink);
973 ISC_LIST_UNLINK(fctx->finds, find, publink);
974 dns_adb_destroyfind(&find);
980 fctx_cleanupaltfinds(fetchctx_t *fctx) {
981 dns_adbfind_t *find, *next_find;
983 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
985 for (find = ISC_LIST_HEAD(fctx->altfinds);
988 next_find = ISC_LIST_NEXT(find, publink);
989 ISC_LIST_UNLINK(fctx->altfinds, find, publink);
990 dns_adb_destroyfind(&find);
992 fctx->altfind = NULL;
996 fctx_cleanupforwaddrs(fetchctx_t *fctx) {
997 dns_adbaddrinfo_t *addr, *next_addr;
999 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
1001 for (addr = ISC_LIST_HEAD(fctx->forwaddrs);
1004 next_addr = ISC_LIST_NEXT(addr, publink);
1005 ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink);
1006 dns_adb_freeaddrinfo(fctx->adb, &addr);
1011 fctx_cleanupaltaddrs(fetchctx_t *fctx) {
1012 dns_adbaddrinfo_t *addr, *next_addr;
1014 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
1016 for (addr = ISC_LIST_HEAD(fctx->altaddrs);
1019 next_addr = ISC_LIST_NEXT(addr, publink);
1020 ISC_LIST_UNLINK(fctx->altaddrs, addr, publink);
1021 dns_adb_freeaddrinfo(fctx->adb, &addr);
1026 fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) {
1027 FCTXTRACE("stopeverything");
1028 fctx_cancelqueries(fctx, no_response);
1029 fctx_cleanupfinds(fctx);
1030 fctx_cleanupaltfinds(fctx);
1031 fctx_cleanupforwaddrs(fctx);
1032 fctx_cleanupaltaddrs(fctx);
1033 fctx_stoptimer(fctx);
1037 fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
1038 dns_fetchevent_t *event, *next_event;
1040 unsigned int count = 0;
1042 isc_boolean_t logit = ISC_FALSE;
1044 unsigned int old_spillat;
1045 unsigned int new_spillat = 0; /* initialized to silence
1046 compiler warnings */
1049 * Caller must be holding the appropriate bucket lock.
1051 REQUIRE(fctx->state == fetchstate_done);
1053 FCTXTRACE("sendevents");
1056 * Keep some record of fetch result for logging later (if required).
1058 fctx->result = result;
1059 fctx->exitline = line;
1061 fctx->duration = isc_time_microdiff(&now, &fctx->start);
1063 for (event = ISC_LIST_HEAD(fctx->events);
1065 event = next_event) {
1066 next_event = ISC_LIST_NEXT(event, ev_link);
1067 ISC_LIST_UNLINK(fctx->events, event, ev_link);
1068 task = event->ev_sender;
1069 event->ev_sender = fctx;
1070 event->vresult = fctx->vresult;
1071 if (!HAVE_ANSWER(fctx))
1072 event->result = result;
1074 INSIST(result != ISC_R_SUCCESS ||
1075 dns_rdataset_isassociated(event->rdataset) ||
1076 fctx->type == dns_rdatatype_any ||
1077 fctx->type == dns_rdatatype_rrsig ||
1078 fctx->type == dns_rdatatype_sig);
1081 * Negative results must be indicated in event->result.
1083 if (dns_rdataset_isassociated(event->rdataset) &&
1084 NEGATIVE(event->rdataset)) {
1085 INSIST(event->result == DNS_R_NCACHENXDOMAIN ||
1086 event->result == DNS_R_NCACHENXRRSET);
1089 isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event));
1093 if ((fctx->attributes & FCTX_ATTR_HAVEANSWER) != 0 &&
1095 (count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) {
1096 LOCK(&fctx->res->lock);
1097 if (count == fctx->res->spillat && !fctx->res->exiting) {
1098 old_spillat = fctx->res->spillat;
1099 fctx->res->spillat += 5;
1100 if (fctx->res->spillat > fctx->res->spillatmax &&
1101 fctx->res->spillatmax != 0)
1102 fctx->res->spillat = fctx->res->spillatmax;
1103 new_spillat = fctx->res->spillat;
1104 if (new_spillat != old_spillat) {
1107 isc_interval_set(&i, 20 * 60, 0);
1108 result = isc_timer_reset(fctx->res->spillattimer,
1109 isc_timertype_ticker, NULL,
1111 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1113 UNLOCK(&fctx->res->lock);
1115 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
1116 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
1117 "clients-per-query increased to %u",
1123 log_edns(fetchctx_t *fctx) {
1124 char domainbuf[DNS_NAME_FORMATSIZE];
1126 if (fctx->reason == NULL)
1129 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
1130 isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
1131 DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
1132 "success resolving '%s' (in '%s'?) after %s",
1133 fctx->info, domainbuf, fctx->reason);
1135 fctx->reason = NULL;
1139 fctx_done(fetchctx_t *fctx, isc_result_t result, int line) {
1140 dns_resolver_t *res;
1141 isc_boolean_t no_response;
1149 if (result == ISC_R_SUCCESS) {
1151 * Log any deferred EDNS timeout messages.
1154 no_response = ISC_TRUE;
1156 no_response = ISC_FALSE;
1158 fctx->reason = NULL;
1159 fctx_stopeverything(fctx, no_response);
1161 LOCK(&res->buckets[fctx->bucketnum].lock);
1163 fctx->state = fetchstate_done;
1164 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
1165 fctx_sendevents(fctx, result, line);
1167 UNLOCK(&res->buckets[fctx->bucketnum].lock);
1171 process_sendevent(resquery_t *query, isc_event_t *event) {
1172 isc_socketevent_t *sevent = (isc_socketevent_t *)event;
1173 isc_boolean_t retry = ISC_FALSE;
1174 isc_result_t result;
1179 if (RESQUERY_CANCELED(query)) {
1180 if (query->sends == 0 && query->connects == 0) {
1182 * This query was canceled while the
1183 * isc_socket_sendto/connect() was in progress.
1185 if (query->tcpsocket != NULL)
1186 isc_socket_detach(&query->tcpsocket);
1187 resquery_destroy(&query);
1190 switch (sevent->result) {
1194 case ISC_R_HOSTUNREACH:
1195 case ISC_R_NETUNREACH:
1197 case ISC_R_ADDRNOTAVAIL:
1198 case ISC_R_CONNREFUSED:
1201 * No route to remote.
1203 add_bad(fctx, query->addrinfo, sevent->result,
1205 fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
1210 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
1215 isc_event_free(&event);
1219 * Behave as if the idle timer has expired. For TCP
1220 * this may not actually reflect the latest timer.
1222 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
1223 result = fctx_stopidletimer(fctx);
1224 if (result != ISC_R_SUCCESS)
1225 fctx_done(fctx, result, __LINE__);
1227 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
1232 resquery_udpconnected(isc_task_t *task, isc_event_t *event) {
1233 resquery_t *query = event->ev_arg;
1235 REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
1237 QTRACE("udpconnected");
1241 INSIST(RESQUERY_CONNECTING(query));
1245 process_sendevent(query, event);
1249 resquery_senddone(isc_task_t *task, isc_event_t *event) {
1250 resquery_t *query = event->ev_arg;
1252 REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
1259 * Currently we don't wait for the senddone event before retrying
1260 * a query. This means that if we get really behind, we may end
1261 * up doing extra work!
1266 INSIST(RESQUERY_SENDING(query));
1270 process_sendevent(query, event);
1273 static inline isc_result_t
1274 fctx_addopt(dns_message_t *message, unsigned int version,
1275 isc_uint16_t udpsize, isc_boolean_t request_nsid)
1277 dns_rdataset_t *rdataset;
1278 dns_rdatalist_t *rdatalist;
1280 isc_result_t result;
1283 result = dns_message_gettemprdatalist(message, &rdatalist);
1284 if (result != ISC_R_SUCCESS)
1287 result = dns_message_gettemprdata(message, &rdata);
1288 if (result != ISC_R_SUCCESS)
1291 result = dns_message_gettemprdataset(message, &rdataset);
1292 if (result != ISC_R_SUCCESS)
1294 dns_rdataset_init(rdataset);
1296 rdatalist->type = dns_rdatatype_opt;
1297 rdatalist->covers = 0;
1300 * Set Maximum UDP buffer size.
1302 rdatalist->rdclass = udpsize;
1305 * Set EXTENDED-RCODE and Z to 0, DO to 1.
1307 rdatalist->ttl = (version << 16);
1308 rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
1311 * Set EDNS options if applicable
1314 /* Send empty NSID option (RFC5001) */
1315 unsigned char data[4];
1318 isc_buffer_init(&buf, data, sizeof(data));
1319 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
1320 isc_buffer_putuint16(&buf, 0);
1322 rdata->length = sizeof(data);
1328 rdata->rdclass = rdatalist->rdclass;
1329 rdata->type = rdatalist->type;
1332 ISC_LIST_INIT(rdatalist->rdata);
1333 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
1334 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS);
1336 return (dns_message_setopt(message, rdataset));
1340 fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
1341 unsigned int seconds;
1345 * We retry every .8 seconds the first two times through the address
1346 * list, and then we do exponential back-off.
1348 if (fctx->restarts < 3)
1351 us = (800000 << (fctx->restarts - 2));
1354 * Double the round-trip time.
1359 * Always wait for at least the doubled round-trip time.
1365 * But don't ever wait for more than 10 seconds.
1370 seconds = us / 1000000;
1371 us -= seconds * 1000000;
1372 isc_interval_set(&fctx->interval, seconds, us * 1000);
1376 fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
1377 unsigned int options)
1379 dns_resolver_t *res;
1381 isc_result_t result;
1383 isc_sockaddr_t addr;
1384 isc_boolean_t have_addr = ISC_FALSE;
1390 task = res->buckets[fctx->bucketnum].task;
1392 srtt = addrinfo->srtt;
1393 if (ISFORWARDER(addrinfo) && srtt < 1000000)
1396 fctx_setretryinterval(fctx, srtt);
1397 result = fctx_startidletimer(fctx, &fctx->interval);
1398 if (result != ISC_R_SUCCESS)
1401 INSIST(ISC_LIST_EMPTY(fctx->validators));
1403 dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE);
1405 query = isc_mem_get(fctx->mctx, sizeof(*query));
1406 if (query == NULL) {
1407 result = ISC_R_NOMEMORY;
1408 goto stop_idle_timer;
1410 query->mctx = fctx->mctx;
1411 query->options = options;
1412 query->attributes = 0;
1414 query->connects = 0;
1416 * Note that the caller MUST guarantee that 'addrinfo' will remain
1417 * valid until this query is canceled.
1419 query->addrinfo = addrinfo;
1420 TIME_NOW(&query->start);
1423 * If this is a TCP query, then we need to make a socket and
1424 * a dispatch for it here. Otherwise we use the resolver's
1427 query->dispatchmgr = res->dispatchmgr;
1428 query->dispatch = NULL;
1429 query->exclusivesocket = ISC_FALSE;
1430 query->tcpsocket = NULL;
1431 if (res->view->peers != NULL) {
1432 dns_peer_t *peer = NULL;
1433 isc_netaddr_t dstip;
1434 isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr);
1435 result = dns_peerlist_peerbyaddr(res->view->peers,
1437 if (result == ISC_R_SUCCESS) {
1438 result = dns_peer_getquerysource(peer, &addr);
1439 if (result == ISC_R_SUCCESS)
1440 have_addr = ISC_TRUE;
1444 if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1447 pf = isc_sockaddr_pf(&addrinfo->sockaddr);
1452 dns_dispatch_getlocaladdress(res->dispatchv4,
1457 dns_dispatch_getlocaladdress(res->dispatchv6,
1461 result = ISC_R_NOTIMPLEMENTED;
1464 if (result != ISC_R_SUCCESS)
1467 isc_sockaddr_setport(&addr, 0);
1469 result = isc_socket_create(res->socketmgr, pf,
1472 if (result != ISC_R_SUCCESS)
1475 #ifndef BROKEN_TCP_BIND_BEFORE_CONNECT
1476 result = isc_socket_bind(query->tcpsocket, &addr, 0);
1477 if (result != ISC_R_SUCCESS)
1478 goto cleanup_socket;
1482 * A dispatch will be created once the connect succeeds.
1486 unsigned int attrs, attrmask;
1487 attrs = DNS_DISPATCHATTR_UDP;
1488 switch (isc_sockaddr_pf(&addr)) {
1490 attrs |= DNS_DISPATCHATTR_IPV4;
1493 attrs |= DNS_DISPATCHATTR_IPV6;
1496 result = ISC_R_NOTIMPLEMENTED;
1499 attrmask = DNS_DISPATCHATTR_UDP;
1500 attrmask |= DNS_DISPATCHATTR_TCP;
1501 attrmask |= DNS_DISPATCHATTR_IPV4;
1502 attrmask |= DNS_DISPATCHATTR_IPV6;
1503 result = dns_dispatch_getudp(res->dispatchmgr,
1505 res->taskmgr, &addr,
1506 4096, 1000, 32768, 16411,
1507 16433, attrs, attrmask,
1509 if (result != ISC_R_SUCCESS)
1512 switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {
1514 dns_dispatch_attach(res->dispatchv4,
1516 query->exclusivesocket = res->exclusivev4;
1519 dns_dispatch_attach(res->dispatchv6,
1521 query->exclusivesocket = res->exclusivev6;
1524 result = ISC_R_NOTIMPLEMENTED;
1529 * We should always have a valid dispatcher here. If we
1530 * don't support a protocol family, then its dispatcher
1531 * will be NULL, but we shouldn't be finding addresses for
1532 * protocol types we don't support, so the dispatcher
1533 * we found should never be NULL.
1535 INSIST(query->dispatch != NULL);
1538 query->dispentry = NULL;
1541 query->tsigkey = NULL;
1542 ISC_LINK_INIT(query, link);
1543 query->magic = QUERY_MAGIC;
1545 if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1547 * Connect to the remote server.
1549 * XXXRTH Should we attach to the socket?
1551 result = isc_socket_connect(query->tcpsocket,
1552 &addrinfo->sockaddr, task,
1553 resquery_connected, query);
1554 if (result != ISC_R_SUCCESS)
1555 goto cleanup_socket;
1557 QTRACE("connecting via TCP");
1559 result = resquery_send(query);
1560 if (result != ISC_R_SUCCESS)
1561 goto cleanup_dispatch;
1566 ISC_LIST_APPEND(fctx->queries, query, link);
1567 query->fctx->nqueries++;
1568 if (isc_sockaddr_pf(&addrinfo->sockaddr) == PF_INET)
1569 inc_stats(res, dns_resstatscounter_queryv4);
1571 inc_stats(res, dns_resstatscounter_queryv6);
1572 if (res->view->resquerystats != NULL)
1573 dns_rdatatypestats_increment(res->view->resquerystats,
1576 return (ISC_R_SUCCESS);
1579 isc_socket_detach(&query->tcpsocket);
1582 if (query->dispatch != NULL)
1583 dns_dispatch_detach(&query->dispatch);
1586 if (query->connects == 0) {
1588 isc_mem_put(fctx->mctx, query, sizeof(*query));
1592 RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS);
1597 static isc_boolean_t
1598 bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1601 for (sa = ISC_LIST_HEAD(fctx->bad_edns);
1603 sa = ISC_LIST_NEXT(sa, link)) {
1604 if (isc_sockaddr_equal(sa, address))
1612 add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1615 if (bad_edns(fctx, address))
1618 sa = isc_mem_get(fctx->mctx, sizeof(*sa));
1623 ISC_LIST_INITANDAPPEND(fctx->bad_edns, sa, link);
1626 static isc_boolean_t
1627 triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1630 for (sa = ISC_LIST_HEAD(fctx->edns);
1632 sa = ISC_LIST_NEXT(sa, link)) {
1633 if (isc_sockaddr_equal(sa, address))
1641 add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) {
1644 if (triededns(fctx, address))
1647 sa = isc_mem_get(fctx->mctx, sizeof(*sa));
1652 ISC_LIST_INITANDAPPEND(fctx->edns, sa, link);
1655 static isc_boolean_t
1656 triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
1659 for (sa = ISC_LIST_HEAD(fctx->edns512);
1661 sa = ISC_LIST_NEXT(sa, link)) {
1662 if (isc_sockaddr_equal(sa, address))
1670 add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
1673 if (triededns512(fctx, address))
1676 sa = isc_mem_get(fctx->mctx, sizeof(*sa));
1681 ISC_LIST_INITANDAPPEND(fctx->edns512, sa, link);
1685 resquery_send(resquery_t *query) {
1687 isc_result_t result;
1688 dns_name_t *qname = NULL;
1689 dns_rdataset_t *qrdataset = NULL;
1691 dns_resolver_t *res;
1693 isc_socket_t *socket;
1694 isc_buffer_t tcpbuffer;
1695 isc_sockaddr_t *address;
1696 isc_buffer_t *buffer;
1697 isc_netaddr_t ipaddr;
1698 dns_tsigkey_t *tsigkey = NULL;
1699 dns_peer_t *peer = NULL;
1700 isc_boolean_t useedns;
1701 dns_compress_t cctx;
1702 isc_boolean_t cleanup_cctx = ISC_FALSE;
1703 isc_boolean_t secure_domain;
1704 isc_boolean_t connecting = ISC_FALSE;
1710 task = res->buckets[fctx->bucketnum].task;
1713 if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1715 * Reserve space for the TCP message length.
1717 isc_buffer_init(&tcpbuffer, query->data, sizeof(query->data));
1718 isc_buffer_init(&query->buffer, query->data + 2,
1719 sizeof(query->data) - 2);
1720 buffer = &tcpbuffer;
1722 isc_buffer_init(&query->buffer, query->data,
1723 sizeof(query->data));
1724 buffer = &query->buffer;
1727 result = dns_message_gettempname(fctx->qmessage, &qname);
1728 if (result != ISC_R_SUCCESS)
1730 result = dns_message_gettemprdataset(fctx->qmessage, &qrdataset);
1731 if (result != ISC_R_SUCCESS)
1735 * Get a query id from the dispatch.
1737 result = dns_dispatch_addresponse2(query->dispatch,
1738 &query->addrinfo->sockaddr,
1745 if (result != ISC_R_SUCCESS)
1748 fctx->qmessage->opcode = dns_opcode_query;
1753 dns_name_init(qname, NULL);
1754 dns_name_clone(&fctx->name, qname);
1755 dns_rdataset_init(qrdataset);
1756 dns_rdataset_makequestion(qrdataset, res->rdclass, fctx->type);
1757 ISC_LIST_APPEND(qname->list, qrdataset, link);
1758 dns_message_addname(fctx->qmessage, qname, DNS_SECTION_QUESTION);
1763 * Set RD if the client has requested that we do a recursive query,
1764 * or if we're sending to a forwarder.
1766 if ((query->options & DNS_FETCHOPT_RECURSIVE) != 0 ||
1767 ISFORWARDER(query->addrinfo))
1768 fctx->qmessage->flags |= DNS_MESSAGEFLAG_RD;
1771 * Set CD if the client says don't validate or the question is
1772 * under a secure entry point.
1774 if ((query->options & DNS_FETCHOPT_NOVALIDATE) != 0) {
1775 fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
1776 } else if (res->view->enablevalidation) {
1777 result = dns_view_issecuredomain(res->view, &fctx->name,
1779 if (result != ISC_R_SUCCESS)
1780 secure_domain = ISC_FALSE;
1781 if (res->view->dlv != NULL)
1782 secure_domain = ISC_TRUE;
1784 fctx->qmessage->flags |= DNS_MESSAGEFLAG_CD;
1788 * We don't have to set opcode because it defaults to query.
1790 fctx->qmessage->id = query->id;
1793 * Convert the question to wire format.
1795 result = dns_compress_init(&cctx, -1, fctx->res->mctx);
1796 if (result != ISC_R_SUCCESS)
1797 goto cleanup_message;
1798 cleanup_cctx = ISC_TRUE;
1800 result = dns_message_renderbegin(fctx->qmessage, &cctx,
1802 if (result != ISC_R_SUCCESS)
1803 goto cleanup_message;
1805 result = dns_message_rendersection(fctx->qmessage,
1806 DNS_SECTION_QUESTION, 0);
1807 if (result != ISC_R_SUCCESS)
1808 goto cleanup_message;
1811 isc_netaddr_fromsockaddr(&ipaddr, &query->addrinfo->sockaddr);
1812 (void) dns_peerlist_peerbyaddr(fctx->res->view->peers, &ipaddr, &peer);
1815 * The ADB does not know about servers with "edns no". Check this,
1816 * and then inform the ADB for future use.
1818 if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0 &&
1820 dns_peer_getsupportedns(peer, &useedns) == ISC_R_SUCCESS &&
1823 query->options |= DNS_FETCHOPT_NOEDNS0;
1824 dns_adb_changeflags(fctx->adb, query->addrinfo,
1825 DNS_FETCHOPT_NOEDNS0,
1826 DNS_FETCHOPT_NOEDNS0);
1829 /* Sync NOEDNS0 flag in addrinfo->flags and options now. */
1830 if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) != 0)
1831 query->options |= DNS_FETCHOPT_NOEDNS0;
1834 * Handle timeouts by reducing the UDP response size to 512 bytes
1835 * then if that doesn't work disabling EDNS (includes DO) and CD.
1837 * These timeout can be due to:
1838 * * broken nameservers that don't respond to EDNS queries.
1839 * * broken/misconfigured firewalls and NAT implementations
1840 * that don't handle IP fragmentation.
1841 * * broken/misconfigured firewalls that don't handle responses
1842 * greater than 512 bytes.
1843 * * broken/misconfigured firewalls that don't handle EDNS, DO
1845 * * packet loss / link outage.
1847 if (fctx->timeout) {
1848 if ((triededns512(fctx, &query->addrinfo->sockaddr) ||
1849 fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) &&
1850 (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
1851 query->options |= DNS_FETCHOPT_NOEDNS0;
1852 fctx->reason = "disabling EDNS";
1853 } else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
1854 fctx->timeouts >= MAX_EDNS0_TIMEOUTS) &&
1855 (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
1856 query->options |= DNS_FETCHOPT_EDNS512;
1857 fctx->reason = "reducing the advertised EDNS UDP "
1858 "packet size to 512 octets";
1860 fctx->timeout = ISC_FALSE;
1864 * Use EDNS0, unless the caller doesn't want it, or we know that
1865 * the remote server doesn't like it.
1867 if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
1868 if ((query->addrinfo->flags & DNS_FETCHOPT_NOEDNS0) == 0) {
1869 unsigned int version = 0; /* Default version. */
1871 isc_uint16_t udpsize = res->udpsize;
1872 isc_boolean_t reqnsid = res->view->requestnsid;
1874 flags = query->addrinfo->flags;
1875 if ((flags & DNS_FETCHOPT_EDNSVERSIONSET) != 0) {
1876 version = flags & DNS_FETCHOPT_EDNSVERSIONMASK;
1877 version >>= DNS_FETCHOPT_EDNSVERSIONSHIFT;
1879 if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
1881 else if (peer != NULL)
1882 (void)dns_peer_getudpsize(peer, &udpsize);
1884 /* request NSID for current view or peer? */
1886 (void) dns_peer_getrequestnsid(peer, &reqnsid);
1887 result = fctx_addopt(fctx->qmessage, version,
1889 if (reqnsid && result == ISC_R_SUCCESS) {
1890 query->options |= DNS_FETCHOPT_WANTNSID;
1891 } else if (result != ISC_R_SUCCESS) {
1893 * We couldn't add the OPT, but we'll press on.
1894 * We're not using EDNS0, so set the NOEDNS0
1897 query->options |= DNS_FETCHOPT_NOEDNS0;
1901 * We know this server doesn't like EDNS0, so we
1902 * won't use it. Set the NOEDNS0 bit since we're
1905 query->options |= DNS_FETCHOPT_NOEDNS0;
1910 * If we need EDNS0 to do this query and aren't using it, we lose.
1912 if (NEEDEDNS0(fctx) && (query->options & DNS_FETCHOPT_NOEDNS0) != 0) {
1913 result = DNS_R_SERVFAIL;
1914 goto cleanup_message;
1917 if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
1918 add_triededns(fctx, &query->addrinfo->sockaddr);
1920 if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
1921 add_triededns512(fctx, &query->addrinfo->sockaddr);
1924 * Clear CD if EDNS is not in use.
1926 if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0)
1927 fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD;
1930 * Add TSIG record tailored to the current recipient.
1932 result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey);
1933 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1934 goto cleanup_message;
1936 if (tsigkey != NULL) {
1937 result = dns_message_settsigkey(fctx->qmessage, tsigkey);
1938 dns_tsigkey_detach(&tsigkey);
1939 if (result != ISC_R_SUCCESS)
1940 goto cleanup_message;
1943 result = dns_message_rendersection(fctx->qmessage,
1944 DNS_SECTION_ADDITIONAL, 0);
1945 if (result != ISC_R_SUCCESS)
1946 goto cleanup_message;
1948 result = dns_message_renderend(fctx->qmessage);
1949 if (result != ISC_R_SUCCESS)
1950 goto cleanup_message;
1952 dns_compress_invalidate(&cctx);
1953 cleanup_cctx = ISC_FALSE;
1955 if (dns_message_gettsigkey(fctx->qmessage) != NULL) {
1956 dns_tsigkey_attach(dns_message_gettsigkey(fctx->qmessage),
1958 result = dns_message_getquerytsig(fctx->qmessage,
1961 if (result != ISC_R_SUCCESS)
1962 goto cleanup_message;
1966 * If using TCP, write the length of the message at the beginning
1969 if ((query->options & DNS_FETCHOPT_TCP) != 0) {
1970 isc_buffer_usedregion(&query->buffer, &r);
1971 isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t)r.length);
1972 isc_buffer_add(&tcpbuffer, r.length);
1976 * We're now done with the query message.
1978 dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
1980 if (query->exclusivesocket)
1981 socket = dns_dispatch_getentrysocket(query->dispentry);
1983 socket = dns_dispatch_getsocket(query->dispatch);
1987 if ((query->options & DNS_FETCHOPT_TCP) == 0) {
1988 address = &query->addrinfo->sockaddr;
1989 if (query->exclusivesocket) {
1990 result = isc_socket_connect(socket, address, task,
1991 resquery_udpconnected,
1993 if (result != ISC_R_SUCCESS)
1994 goto cleanup_message;
1995 connecting = ISC_TRUE;
1999 isc_buffer_usedregion(buffer, &r);
2002 * XXXRTH Make sure we don't send to ourselves! We should probably
2003 * prune out these addresses when we get them from the ADB.
2005 result = isc_socket_sendto(socket, &r, task, resquery_senddone,
2006 query, address, NULL);
2007 if (result != ISC_R_SUCCESS) {
2010 * This query is still connecting.
2011 * Mark it as canceled so that it will just be
2012 * cleaned up when the connected event is received.
2013 * Keep fctx around until the event is processed.
2015 query->fctx->nqueries++;
2016 query->attributes |= RESQUERY_ATTR_CANCELED;
2018 goto cleanup_message;
2025 return (ISC_R_SUCCESS);
2029 dns_compress_invalidate(&cctx);
2031 dns_message_reset(fctx->qmessage, DNS_MESSAGE_INTENTRENDER);
2034 * Stop the dispatcher from listening.
2036 dns_dispatch_removeresponse(&query->dispentry, NULL);
2040 dns_message_puttempname(fctx->qmessage, &qname);
2041 if (qrdataset != NULL)
2042 dns_message_puttemprdataset(fctx->qmessage, &qrdataset);
2048 resquery_connected(isc_task_t *task, isc_event_t *event) {
2049 isc_socketevent_t *sevent = (isc_socketevent_t *)event;
2050 resquery_t *query = event->ev_arg;
2051 isc_boolean_t retry = ISC_FALSE;
2052 isc_interval_t interval;
2053 isc_result_t result;
2057 REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
2058 REQUIRE(VALID_QUERY(query));
2060 QTRACE("connected");
2067 * Currently we don't wait for the connect event before retrying
2068 * a query. This means that if we get really behind, we may end
2069 * up doing extra work!
2075 if (RESQUERY_CANCELED(query)) {
2077 * This query was canceled while the connect() was in
2080 isc_socket_detach(&query->tcpsocket);
2081 resquery_destroy(&query);
2083 switch (sevent->result) {
2087 * Extend the idle timer for TCP. 20 seconds
2088 * should be long enough for a TCP connection to be
2089 * established, a single DNS request to be sent,
2090 * and the response received.
2092 isc_interval_set(&interval, 20, 0);
2093 result = fctx_startidletimer(query->fctx, &interval);
2094 if (result != ISC_R_SUCCESS) {
2095 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
2096 fctx_done(fctx, result, __LINE__);
2100 * We are connected. Create a dispatcher and
2104 attrs |= DNS_DISPATCHATTR_TCP;
2105 attrs |= DNS_DISPATCHATTR_PRIVATE;
2106 attrs |= DNS_DISPATCHATTR_CONNECTED;
2107 if (isc_sockaddr_pf(&query->addrinfo->sockaddr) ==
2109 attrs |= DNS_DISPATCHATTR_IPV4;
2111 attrs |= DNS_DISPATCHATTR_IPV6;
2112 attrs |= DNS_DISPATCHATTR_MAKEQUERY;
2114 result = dns_dispatch_createtcp(query->dispatchmgr,
2116 query->fctx->res->taskmgr,
2117 4096, 2, 1, 1, 3, attrs,
2121 * Regardless of whether dns_dispatch_create()
2122 * succeeded or not, we don't need our reference
2123 * to the socket anymore.
2125 isc_socket_detach(&query->tcpsocket);
2127 if (result == ISC_R_SUCCESS)
2128 result = resquery_send(query);
2130 if (result != ISC_R_SUCCESS) {
2131 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
2132 fctx_done(fctx, result, __LINE__);
2136 case ISC_R_NETUNREACH:
2137 case ISC_R_HOSTUNREACH:
2138 case ISC_R_CONNREFUSED:
2140 case ISC_R_ADDRNOTAVAIL:
2141 case ISC_R_CONNECTIONRESET:
2143 * No route to remote.
2145 isc_socket_detach(&query->tcpsocket);
2146 fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
2151 isc_socket_detach(&query->tcpsocket);
2152 fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
2157 isc_event_free(&event);
2161 * Behave as if the idle timer has expired. For TCP
2162 * connections this may not actually reflect the latest timer.
2164 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
2165 result = fctx_stopidletimer(fctx);
2166 if (result != ISC_R_SUCCESS)
2167 fctx_done(fctx, result, __LINE__);
2169 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
2174 fctx_finddone(isc_task_t *task, isc_event_t *event) {
2176 dns_adbfind_t *find;
2177 dns_resolver_t *res;
2178 isc_boolean_t want_try = ISC_FALSE;
2179 isc_boolean_t want_done = ISC_FALSE;
2180 isc_boolean_t bucket_empty = ISC_FALSE;
2181 unsigned int bucketnum;
2182 isc_boolean_t destroy = ISC_FALSE;
2184 find = event->ev_sender;
2185 fctx = event->ev_arg;
2186 REQUIRE(VALID_FCTX(fctx));
2191 FCTXTRACE("finddone");
2193 bucketnum = fctx->bucketnum;
2194 LOCK(&res->buckets[bucketnum].lock);
2196 INSIST(fctx->pending > 0);
2199 if (ADDRWAIT(fctx)) {
2201 * The fetch is waiting for a name to be found.
2203 INSIST(!SHUTTINGDOWN(fctx));
2204 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
2205 if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) {
2206 want_try = ISC_TRUE;
2209 if (fctx->pending == 0) {
2211 * We've got nothing else to wait for and don't
2212 * know the answer. There's nothing to do but
2215 want_done = ISC_TRUE;
2218 } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
2219 fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
2221 if (fctx->references == 0) {
2222 bucket_empty = fctx_unlink(fctx);
2226 UNLOCK(&res->buckets[bucketnum].lock);
2228 isc_event_free(&event);
2229 dns_adb_destroyfind(&find);
2232 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
2234 fctx_done(fctx, ISC_R_FAILURE, __LINE__);
2243 static inline isc_boolean_t
2244 bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) {
2247 for (sa = ISC_LIST_HEAD(fctx->bad);
2249 sa = ISC_LIST_NEXT(sa, link)) {
2250 if (isc_sockaddr_equal(sa, address))
2257 static inline isc_boolean_t
2258 mark_bad(fetchctx_t *fctx) {
2259 dns_adbfind_t *curr;
2260 dns_adbaddrinfo_t *addrinfo;
2261 isc_boolean_t all_bad = ISC_TRUE;
2264 * Mark all known bad servers, so we don't try to talk to them
2269 * Mark any bad nameservers.
2271 for (curr = ISC_LIST_HEAD(fctx->finds);
2273 curr = ISC_LIST_NEXT(curr, publink)) {
2274 for (addrinfo = ISC_LIST_HEAD(curr->list);
2276 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2277 if (bad_server(fctx, &addrinfo->sockaddr))
2278 addrinfo->flags |= FCTX_ADDRINFO_MARK;
2280 all_bad = ISC_FALSE;
2285 * Mark any bad forwarders.
2287 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
2289 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2290 if (bad_server(fctx, &addrinfo->sockaddr))
2291 addrinfo->flags |= FCTX_ADDRINFO_MARK;
2293 all_bad = ISC_FALSE;
2297 * Mark any bad alternates.
2299 for (curr = ISC_LIST_HEAD(fctx->altfinds);
2301 curr = ISC_LIST_NEXT(curr, publink)) {
2302 for (addrinfo = ISC_LIST_HEAD(curr->list);
2304 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2305 if (bad_server(fctx, &addrinfo->sockaddr))
2306 addrinfo->flags |= FCTX_ADDRINFO_MARK;
2308 all_bad = ISC_FALSE;
2312 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
2314 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2315 if (bad_server(fctx, &addrinfo->sockaddr))
2316 addrinfo->flags |= FCTX_ADDRINFO_MARK;
2318 all_bad = ISC_FALSE;
2325 add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason,
2326 badnstype_t badtype)
2328 char namebuf[DNS_NAME_FORMATSIZE];
2329 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
2335 const char *spc = "";
2336 isc_sockaddr_t *address = &addrinfo->sockaddr;
2338 if (reason == DNS_R_LAME)
2342 case badns_unreachable:
2345 case badns_response:
2348 case badns_validation:
2349 break; /* counted as 'valfail' */
2353 if (bad_server(fctx, address)) {
2355 * We already know this server is bad.
2360 FCTXTRACE("add_bad");
2362 sa = isc_mem_get(fctx->mctx, sizeof(*sa));
2366 ISC_LIST_INITANDAPPEND(fctx->bad, sa, link);
2368 if (reason == DNS_R_LAME) /* already logged */
2371 if (reason == DNS_R_UNEXPECTEDRCODE &&
2372 fctx->rmessage->rcode == dns_rcode_servfail &&
2373 ISFORWARDER(addrinfo))
2376 if (reason == DNS_R_UNEXPECTEDRCODE) {
2377 isc_buffer_init(&b, code, sizeof(code) - 1);
2378 dns_rcode_totext(fctx->rmessage->rcode, &b);
2379 code[isc_buffer_usedlength(&b)] = '\0';
2381 } else if (reason == DNS_R_UNEXPECTEDOPCODE) {
2382 isc_buffer_init(&b, code, sizeof(code) - 1);
2383 dns_opcode_totext((dns_opcode_t)fctx->rmessage->opcode, &b);
2384 code[isc_buffer_usedlength(&b)] = '\0';
2389 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
2390 dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
2391 dns_rdataclass_format(fctx->res->rdclass, classbuf, sizeof(classbuf));
2392 isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));
2393 isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
2394 DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
2395 "error (%s%s%s) resolving '%s/%s/%s': %s",
2396 dns_result_totext(reason), spc, code,
2397 namebuf, typebuf, classbuf, addrbuf);
2401 * Sort addrinfo list by RTT.
2404 sort_adbfind(dns_adbfind_t *find) {
2405 dns_adbaddrinfo_t *best, *curr;
2406 dns_adbaddrinfolist_t sorted;
2408 /* Lame N^2 bubble sort. */
2409 ISC_LIST_INIT(sorted);
2410 while (!ISC_LIST_EMPTY(find->list)) {
2411 best = ISC_LIST_HEAD(find->list);
2412 curr = ISC_LIST_NEXT(best, publink);
2413 while (curr != NULL) {
2414 if (curr->srtt < best->srtt)
2416 curr = ISC_LIST_NEXT(curr, publink);
2418 ISC_LIST_UNLINK(find->list, best, publink);
2419 ISC_LIST_APPEND(sorted, best, publink);
2421 find->list = sorted;
2425 * Sort a list of finds by server RTT.
2428 sort_finds(dns_adbfindlist_t *findlist) {
2429 dns_adbfind_t *best, *curr;
2430 dns_adbfindlist_t sorted;
2431 dns_adbaddrinfo_t *addrinfo, *bestaddrinfo;
2433 /* Sort each find's addrinfo list by SRTT. */
2434 for (curr = ISC_LIST_HEAD(*findlist);
2436 curr = ISC_LIST_NEXT(curr, publink))
2439 /* Lame N^2 bubble sort. */
2440 ISC_LIST_INIT(sorted);
2441 while (!ISC_LIST_EMPTY(*findlist)) {
2442 best = ISC_LIST_HEAD(*findlist);
2443 bestaddrinfo = ISC_LIST_HEAD(best->list);
2444 INSIST(bestaddrinfo != NULL);
2445 curr = ISC_LIST_NEXT(best, publink);
2446 while (curr != NULL) {
2447 addrinfo = ISC_LIST_HEAD(curr->list);
2448 INSIST(addrinfo != NULL);
2449 if (addrinfo->srtt < bestaddrinfo->srtt) {
2451 bestaddrinfo = addrinfo;
2453 curr = ISC_LIST_NEXT(curr, publink);
2455 ISC_LIST_UNLINK(*findlist, best, publink);
2456 ISC_LIST_APPEND(sorted, best, publink);
2462 findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
2463 unsigned int options, unsigned int flags, isc_stdtime_t now,
2464 isc_boolean_t *need_alternate)
2466 dns_adbaddrinfo_t *ai;
2467 dns_adbfind_t *find;
2468 dns_resolver_t *res;
2469 isc_boolean_t unshared;
2470 isc_result_t result;
2473 unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0);
2475 * If this name is a subdomain of the query domain, tell
2476 * the ADB to start looking using zone/hint data. This keeps us
2477 * from getting stuck if the nameserver is beneath the zone cut
2478 * and we don't know its address (e.g. because the A record has
2481 if (dns_name_issubdomain(name, &fctx->domain))
2482 options |= DNS_ADBFIND_STARTATZONE;
2483 options |= DNS_ADBFIND_GLUEOK;
2484 options |= DNS_ADBFIND_HINTOK;
2487 * See what we know about this address.
2490 result = dns_adb_createfind2(fctx->adb,
2491 res->buckets[fctx->bucketnum].task,
2492 fctx_finddone, fctx, name,
2493 &fctx->name, fctx->type,
2496 fctx->depth + 1, fctx->qc, &find);
2497 if (result != ISC_R_SUCCESS) {
2498 if (result == DNS_R_ALIAS) {
2500 * XXXRTH Follow the CNAME/DNAME chain?
2502 dns_adb_destroyfind(&find);
2505 } else if (!ISC_LIST_EMPTY(find->list)) {
2507 * We have at least some of the addresses for the
2510 INSIST((find->options & DNS_ADBFIND_WANTEVENT) == 0);
2511 if (flags != 0 || port != 0) {
2512 for (ai = ISC_LIST_HEAD(find->list);
2514 ai = ISC_LIST_NEXT(ai, publink)) {
2517 isc_sockaddr_setport(&ai->sockaddr,
2521 if ((flags & FCTX_ADDRINFO_FORWARDER) != 0)
2522 ISC_LIST_APPEND(fctx->altfinds, find, publink);
2524 ISC_LIST_APPEND(fctx->finds, find, publink);
2527 * We don't know any of the addresses for this
2530 if ((find->options & DNS_ADBFIND_WANTEVENT) != 0) {
2532 * We're looking for them and will get an
2533 * event about it later.
2539 if (need_alternate != NULL &&
2540 !*need_alternate && unshared &&
2541 ((res->dispatchv4 == NULL &&
2542 find->result_v6 != DNS_R_NXDOMAIN) ||
2543 (res->dispatchv6 == NULL &&
2544 find->result_v4 != DNS_R_NXDOMAIN)))
2545 *need_alternate = ISC_TRUE;
2547 if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0)
2548 fctx->lamecount++; /* cached lame server */
2550 fctx->adberr++; /* unreachable server, etc. */
2553 * If we know there are no addresses for
2554 * the family we are using then try to add
2555 * an alternative server.
2557 if (need_alternate != NULL && !*need_alternate &&
2558 ((res->dispatchv4 == NULL &&
2559 find->result_v6 == DNS_R_NXRRSET) ||
2560 (res->dispatchv6 == NULL &&
2561 find->result_v4 == DNS_R_NXRRSET)))
2562 *need_alternate = ISC_TRUE;
2563 dns_adb_destroyfind(&find);
2568 static isc_boolean_t
2569 isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) {
2571 unsigned int nlabels;
2572 dns_namereln_t namereln;
2574 namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
2575 return (ISC_TF(namereln == dns_namereln_subdomain));
2579 fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
2580 dns_rdata_t rdata = DNS_RDATA_INIT;
2581 isc_result_t result;
2582 dns_resolver_t *res;
2584 unsigned int stdoptions = 0;
2586 dns_adbaddrinfo_t *ai;
2587 isc_boolean_t all_bad;
2589 isc_boolean_t need_alternate = ISC_FALSE;
2591 FCTXTRACE("getaddresses");
2594 * Don't pound on remote servers. (Failsafe!)
2597 if (fctx->restarts > 10) {
2598 FCTXTRACE("too many restarts");
2599 return (DNS_R_SERVFAIL);
2604 if (fctx->depth > res->maxdepth) {
2605 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
2606 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
2607 "too much NS indirection resolving '%s'",
2609 return (DNS_R_SERVFAIL);
2616 INSIST(ISC_LIST_EMPTY(fctx->forwaddrs));
2617 INSIST(ISC_LIST_EMPTY(fctx->altaddrs));
2620 * If this fctx has forwarders, use them; otherwise use any
2621 * selective forwarders specified in the view; otherwise use the
2622 * resolver's forwarders (if any).
2624 sa = ISC_LIST_HEAD(fctx->forwarders);
2626 dns_forwarders_t *forwarders = NULL;
2627 dns_name_t *name = &fctx->name;
2629 unsigned int labels;
2630 dns_fixedname_t fixed;
2634 * DS records are found in the parent server.
2635 * Strip label to get the correct forwarder (if any).
2637 if (dns_rdatatype_atparent(fctx->type) &&
2638 dns_name_countlabels(name) > 1) {
2639 dns_name_init(&suffix, NULL);
2640 labels = dns_name_countlabels(name);
2641 dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
2645 dns_fixedname_init(&fixed);
2646 domain = dns_fixedname_name(&fixed);
2647 result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
2648 domain, &forwarders);
2649 if (result == ISC_R_SUCCESS) {
2650 sa = ISC_LIST_HEAD(forwarders->addrs);
2651 fctx->fwdpolicy = forwarders->fwdpolicy;
2652 if (fctx->fwdpolicy == dns_fwdpolicy_only &&
2653 isstrictsubdomain(domain, &fctx->domain)) {
2654 dns_name_free(&fctx->domain, fctx->mctx);
2655 dns_name_init(&fctx->domain, NULL);
2656 result = dns_name_dup(domain, fctx->mctx,
2658 if (result != ISC_R_SUCCESS)
2664 while (sa != NULL) {
2665 if ((isc_sockaddr_pf(sa) == AF_INET &&
2666 fctx->res->dispatchv4 == NULL) ||
2667 (isc_sockaddr_pf(sa) == AF_INET6 &&
2668 fctx->res->dispatchv6 == NULL)) {
2669 sa = ISC_LIST_NEXT(sa, link);
2673 result = dns_adb_findaddrinfo(fctx->adb,
2674 sa, &ai, 0); /* XXXMLG */
2675 if (result == ISC_R_SUCCESS) {
2676 dns_adbaddrinfo_t *cur;
2677 ai->flags |= FCTX_ADDRINFO_FORWARDER;
2678 cur = ISC_LIST_HEAD(fctx->forwaddrs);
2679 while (cur != NULL && cur->srtt < ai->srtt)
2680 cur = ISC_LIST_NEXT(cur, publink);
2682 ISC_LIST_INSERTBEFORE(fctx->forwaddrs, cur,
2685 ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
2687 sa = ISC_LIST_NEXT(sa, link);
2691 * If the forwarding policy is "only", we don't need the addresses
2692 * of the nameservers.
2694 if (fctx->fwdpolicy == dns_fwdpolicy_only)
2698 * Normal nameservers.
2701 stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT;
2702 if (fctx->restarts == 1) {
2704 * To avoid sending out a flood of queries likely to
2705 * result in NXRRSET, we suppress fetches for address
2706 * families we don't have the first time through,
2707 * provided that we have addresses in some family we
2710 * We don't want to set this option all the time, since
2711 * if fctx->restarts > 1, we've clearly been having trouble
2712 * with the addresses we had, so getting more could help.
2714 stdoptions |= DNS_ADBFIND_AVOIDFETCHES;
2716 if (res->dispatchv4 != NULL)
2717 stdoptions |= DNS_ADBFIND_INET;
2718 if (res->dispatchv6 != NULL)
2719 stdoptions |= DNS_ADBFIND_INET6;
2720 isc_stdtime_get(&now);
2722 INSIST(ISC_LIST_EMPTY(fctx->finds));
2723 INSIST(ISC_LIST_EMPTY(fctx->altfinds));
2725 for (result = dns_rdataset_first(&fctx->nameservers);
2726 result == ISC_R_SUCCESS;
2727 result = dns_rdataset_next(&fctx->nameservers))
2729 dns_rdataset_current(&fctx->nameservers, &rdata);
2731 * Extract the name from the NS record.
2733 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2734 if (result != ISC_R_SUCCESS)
2737 findname(fctx, &ns.name, 0, stdoptions, 0, now,
2739 dns_rdata_reset(&rdata);
2740 dns_rdata_freestruct(&ns);
2742 if (result != ISC_R_NOMORE)
2746 * Do we need to use 6 to 4?
2748 if (need_alternate) {
2751 family = (res->dispatchv6 != NULL) ? AF_INET6 : AF_INET;
2752 for (a = ISC_LIST_HEAD(fctx->res->alternates);
2754 a = ISC_LIST_NEXT(a, link)) {
2755 if (!a->isaddress) {
2756 findname(fctx, &a->_u._n.name, a->_u._n.port,
2757 stdoptions, FCTX_ADDRINFO_FORWARDER,
2761 if (isc_sockaddr_pf(&a->_u.addr) != family)
2764 result = dns_adb_findaddrinfo(fctx->adb, &a->_u.addr,
2766 if (result == ISC_R_SUCCESS) {
2767 dns_adbaddrinfo_t *cur;
2768 ai->flags |= FCTX_ADDRINFO_FORWARDER;
2769 cur = ISC_LIST_HEAD(fctx->altaddrs);
2770 while (cur != NULL && cur->srtt < ai->srtt)
2771 cur = ISC_LIST_NEXT(cur, publink);
2773 ISC_LIST_INSERTBEFORE(fctx->altaddrs,
2776 ISC_LIST_APPEND(fctx->altaddrs, ai,
2784 * Mark all known bad servers.
2786 all_bad = mark_bad(fctx);
2793 * We've got no addresses.
2795 if (fctx->pending > 0) {
2797 * We're fetching the addresses, but don't have any
2798 * yet. Tell the caller to wait for an answer.
2800 result = DNS_R_WAIT;
2805 * We've lost completely. We don't know any
2806 * addresses, and the ADB has told us it can't get
2809 FCTXTRACE("no addresses");
2810 isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
2811 result = isc_time_nowplusinterval(&expire, &i);
2813 (fctx->type == dns_rdatatype_dnskey ||
2814 fctx->type == dns_rdatatype_dlv ||
2815 fctx->type == dns_rdatatype_ds) &&
2816 result == ISC_R_SUCCESS)
2817 dns_resolver_addbadcache(fctx->res,
2819 fctx->type, &expire);
2820 result = ISC_R_FAILURE;
2824 * We've found some addresses. We might still be looking
2825 * for more addresses.
2827 sort_finds(&fctx->finds);
2828 sort_finds(&fctx->altfinds);
2829 result = ISC_R_SUCCESS;
2836 possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr)
2839 char buf[ISC_NETADDR_FORMATSIZE];
2841 isc_boolean_t aborted = ISC_FALSE;
2842 isc_boolean_t bogus;
2843 dns_acl_t *blackhole;
2844 isc_netaddr_t ipaddr;
2845 dns_peer_t *peer = NULL;
2846 dns_resolver_t *res;
2847 const char *msg = NULL;
2849 sa = &addr->sockaddr;
2852 isc_netaddr_fromsockaddr(&ipaddr, sa);
2853 blackhole = dns_dispatchmgr_getblackhole(res->dispatchmgr);
2854 (void) dns_peerlist_peerbyaddr(res->view->peers, &ipaddr, &peer);
2856 if (blackhole != NULL) {
2859 if (dns_acl_match(&ipaddr, NULL, blackhole,
2861 &match, NULL) == ISC_R_SUCCESS &&
2867 dns_peer_getbogus(peer, &bogus) == ISC_R_SUCCESS &&
2872 addr->flags |= FCTX_ADDRINFO_MARK;
2873 msg = "ignoring blackholed / bogus server: ";
2874 } else if (isc_sockaddr_ismulticast(sa)) {
2875 addr->flags |= FCTX_ADDRINFO_MARK;
2876 msg = "ignoring multicast address: ";
2877 } else if (isc_sockaddr_isexperimental(sa)) {
2878 addr->flags |= FCTX_ADDRINFO_MARK;
2879 msg = "ignoring experimental address: ";
2880 } else if (sa->type.sa.sa_family != AF_INET6) {
2882 } else if (IN6_IS_ADDR_V4MAPPED(&sa->type.sin6.sin6_addr)) {
2883 addr->flags |= FCTX_ADDRINFO_MARK;
2884 msg = "ignoring IPv6 mapped IPV4 address: ";
2885 } else if (IN6_IS_ADDR_V4COMPAT(&sa->type.sin6.sin6_addr)) {
2886 addr->flags |= FCTX_ADDRINFO_MARK;
2887 msg = "ignoring IPv6 compatibility IPV4 address: ";
2891 if (!isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3)))
2894 isc_netaddr_fromsockaddr(&na, sa);
2895 isc_netaddr_format(&na, buf, sizeof(buf));
2896 FCTXTRACE2(msg, buf);
2899 static inline dns_adbaddrinfo_t *
2900 fctx_nextaddress(fetchctx_t *fctx) {
2901 dns_adbfind_t *find, *start;
2902 dns_adbaddrinfo_t *addrinfo;
2903 dns_adbaddrinfo_t *faddrinfo;
2906 * Return the next untried address, if any.
2910 * Find the first unmarked forwarder (if any).
2912 for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
2914 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2915 if (!UNMARKED(addrinfo))
2917 possibly_mark(fctx, addrinfo);
2918 if (UNMARKED(addrinfo)) {
2919 addrinfo->flags |= FCTX_ADDRINFO_MARK;
2926 * No forwarders. Move to the next find.
2929 fctx->attributes |= FCTX_ATTR_TRIEDFIND;
2933 find = ISC_LIST_HEAD(fctx->finds);
2935 find = ISC_LIST_NEXT(find, publink);
2937 find = ISC_LIST_HEAD(fctx->finds);
2941 * Find the first unmarked addrinfo.
2947 for (addrinfo = ISC_LIST_HEAD(find->list);
2949 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2950 if (!UNMARKED(addrinfo))
2952 possibly_mark(fctx, addrinfo);
2953 if (UNMARKED(addrinfo)) {
2954 addrinfo->flags |= FCTX_ADDRINFO_MARK;
2958 if (addrinfo != NULL)
2960 find = ISC_LIST_NEXT(find, publink);
2962 find = ISC_LIST_HEAD(fctx->finds);
2963 } while (find != start);
2967 if (addrinfo != NULL)
2971 * No nameservers left. Try alternates.
2974 fctx->attributes |= FCTX_ATTR_TRIEDALT;
2976 find = fctx->altfind;
2978 find = ISC_LIST_HEAD(fctx->altfinds);
2980 find = ISC_LIST_NEXT(find, publink);
2982 find = ISC_LIST_HEAD(fctx->altfinds);
2986 * Find the first unmarked addrinfo.
2992 for (addrinfo = ISC_LIST_HEAD(find->list);
2994 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
2995 if (!UNMARKED(addrinfo))
2997 possibly_mark(fctx, addrinfo);
2998 if (UNMARKED(addrinfo)) {
2999 addrinfo->flags |= FCTX_ADDRINFO_MARK;
3003 if (addrinfo != NULL)
3005 find = ISC_LIST_NEXT(find, publink);
3007 find = ISC_LIST_HEAD(fctx->altfinds);
3008 } while (find != start);
3011 faddrinfo = addrinfo;
3014 * See if we have a better alternate server by address.
3017 for (addrinfo = ISC_LIST_HEAD(fctx->altaddrs);
3019 addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
3020 if (!UNMARKED(addrinfo))
3022 possibly_mark(fctx, addrinfo);
3023 if (UNMARKED(addrinfo) &&
3024 (faddrinfo == NULL ||
3025 addrinfo->srtt < faddrinfo->srtt)) {
3026 if (faddrinfo != NULL)
3027 faddrinfo->flags &= ~FCTX_ADDRINFO_MARK;
3028 addrinfo->flags |= FCTX_ADDRINFO_MARK;
3033 if (addrinfo == NULL) {
3034 addrinfo = faddrinfo;
3035 fctx->altfind = find;
3042 fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
3043 isc_result_t result;
3044 dns_adbaddrinfo_t *addrinfo;
3048 REQUIRE(!ADDRWAIT(fctx));
3050 addrinfo = fctx_nextaddress(fctx);
3051 if (addrinfo == NULL) {
3053 * We have no more addresses. Start over.
3055 fctx_cancelqueries(fctx, ISC_TRUE);
3056 fctx_cleanupfinds(fctx);
3057 fctx_cleanupaltfinds(fctx);
3058 fctx_cleanupforwaddrs(fctx);
3059 fctx_cleanupaltaddrs(fctx);
3060 result = fctx_getaddresses(fctx, badcache);
3061 if (result == DNS_R_WAIT) {
3063 * Sleep waiting for addresses.
3065 FCTXTRACE("addrwait");
3066 fctx->attributes |= FCTX_ATTR_ADDRWAIT;
3068 } else if (result != ISC_R_SUCCESS) {
3070 * Something bad happened.
3072 fctx_done(fctx, result, __LINE__);
3076 addrinfo = fctx_nextaddress(fctx);
3078 * While we may have addresses from the ADB, they
3079 * might be bad ones. In this case, return SERVFAIL.
3081 if (addrinfo == NULL) {
3082 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
3087 result = isc_counter_increment(fctx->qc);
3088 if (result != ISC_R_SUCCESS) {
3089 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
3090 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
3091 "exceeded max queries resolving '%s'",
3093 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
3097 result = fctx_query(fctx, addrinfo, fctx->options);
3098 if (result != ISC_R_SUCCESS)
3099 fctx_done(fctx, result, __LINE__);
3101 inc_stats(fctx->res, dns_resstatscounter_retry);
3104 static isc_boolean_t
3105 fctx_unlink(fetchctx_t *fctx) {
3106 dns_resolver_t *res;
3107 unsigned int bucketnum;
3110 * Caller must be holding the bucket lock.
3113 REQUIRE(VALID_FCTX(fctx));
3114 REQUIRE(fctx->state == fetchstate_done ||
3115 fctx->state == fetchstate_init);
3116 REQUIRE(ISC_LIST_EMPTY(fctx->events));
3117 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
3118 REQUIRE(ISC_LIST_EMPTY(fctx->finds));
3119 REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
3120 REQUIRE(fctx->pending == 0);
3121 REQUIRE(fctx->references == 0);
3122 REQUIRE(ISC_LIST_EMPTY(fctx->validators));
3124 FCTXTRACE("unlink");
3127 bucketnum = fctx->bucketnum;
3129 ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
3133 UNLOCK(&res->nlock);
3135 if (res->buckets[bucketnum].exiting &&
3136 ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs))
3143 fctx_destroy(fetchctx_t *fctx) {
3144 isc_sockaddr_t *sa, *next_sa;
3146 REQUIRE(VALID_FCTX(fctx));
3147 REQUIRE(fctx->state == fetchstate_done ||
3148 fctx->state == fetchstate_init);
3149 REQUIRE(ISC_LIST_EMPTY(fctx->events));
3150 REQUIRE(ISC_LIST_EMPTY(fctx->queries));
3151 REQUIRE(ISC_LIST_EMPTY(fctx->finds));
3152 REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
3153 REQUIRE(fctx->pending == 0);
3154 REQUIRE(fctx->references == 0);
3155 REQUIRE(ISC_LIST_EMPTY(fctx->validators));
3156 REQUIRE(!ISC_LINK_LINKED(fctx, link));
3158 FCTXTRACE("destroy");
3163 for (sa = ISC_LIST_HEAD(fctx->bad);
3166 next_sa = ISC_LIST_NEXT(sa, link);
3167 ISC_LIST_UNLINK(fctx->bad, sa, link);
3168 isc_mem_put(fctx->mctx, sa, sizeof(*sa));
3171 for (sa = ISC_LIST_HEAD(fctx->edns);
3174 next_sa = ISC_LIST_NEXT(sa, link);
3175 ISC_LIST_UNLINK(fctx->edns, sa, link);
3176 isc_mem_put(fctx->mctx, sa, sizeof(*sa));
3179 for (sa = ISC_LIST_HEAD(fctx->edns512);
3182 next_sa = ISC_LIST_NEXT(sa, link);
3183 ISC_LIST_UNLINK(fctx->edns512, sa, link);
3184 isc_mem_put(fctx->mctx, sa, sizeof(*sa));
3187 for (sa = ISC_LIST_HEAD(fctx->bad_edns);
3190 next_sa = ISC_LIST_NEXT(sa, link);
3191 ISC_LIST_UNLINK(fctx->bad_edns, sa, link);
3192 isc_mem_put(fctx->mctx, sa, sizeof(*sa));
3195 isc_counter_detach(&fctx->qc);
3196 isc_timer_detach(&fctx->timer);
3197 dns_message_destroy(&fctx->rmessage);
3198 dns_message_destroy(&fctx->qmessage);
3199 if (dns_name_countlabels(&fctx->domain) > 0)
3200 dns_name_free(&fctx->domain, fctx->mctx);
3201 if (dns_rdataset_isassociated(&fctx->nameservers))
3202 dns_rdataset_disassociate(&fctx->nameservers);
3203 dns_name_free(&fctx->name, fctx->mctx);
3204 dns_db_detach(&fctx->cache);
3205 dns_adb_detach(&fctx->adb);
3206 isc_mem_free(fctx->mctx, fctx->info);
3207 isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx));
3211 * Fetch event handlers.
3215 fctx_timeout(isc_task_t *task, isc_event_t *event) {
3216 fetchctx_t *fctx = event->ev_arg;
3217 isc_timerevent_t *tevent = (isc_timerevent_t *)event;
3220 REQUIRE(VALID_FCTX(fctx));
3224 FCTXTRACE("timeout");
3226 inc_stats(fctx->res, dns_resstatscounter_querytimeout);
3228 if (event->ev_type == ISC_TIMEREVENT_LIFE) {
3229 fctx->reason = NULL;
3230 fctx_done(fctx, ISC_R_TIMEDOUT, __LINE__);
3232 isc_result_t result;
3235 fctx->timeout = ISC_TRUE;
3237 * We could cancel the running queries here, or we could let
3238 * them keep going. Since we normally use separate sockets for
3239 * different queries, we adopt the former approach to reduce
3240 * the number of open sockets: cancel the oldest query if it
3241 * expired after the query had started (this is usually the
3242 * case but is not always so, depending on the task schedule
3245 query = ISC_LIST_HEAD(fctx->queries);
3246 if (query != NULL &&
3247 isc_time_compare(&tevent->due, &query->start) >= 0) {
3248 fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
3250 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
3252 * Our timer has triggered. Reestablish the fctx lifetime
3255 result = fctx_starttimer(fctx);
3256 if (result != ISC_R_SUCCESS)
3257 fctx_done(fctx, result, __LINE__);
3262 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
3265 isc_event_free(&event);
3269 fctx_shutdown(fetchctx_t *fctx) {
3270 isc_event_t *cevent;
3273 * Start the shutdown process for fctx, if it isn't already underway.
3276 FCTXTRACE("shutdown");
3279 * The caller must be holding the appropriate bucket lock.
3282 if (fctx->want_shutdown)
3285 fctx->want_shutdown = ISC_TRUE;
3288 * Unless we're still initializing (in which case the
3289 * control event is still outstanding), we need to post
3290 * the control event to tell the fetch we want it to
3293 if (fctx->state != fetchstate_init) {
3294 cevent = &fctx->control_event;
3295 isc_task_send(fctx->res->buckets[fctx->bucketnum].task,
3301 fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
3302 fetchctx_t *fctx = event->ev_arg;
3303 isc_boolean_t bucket_empty = ISC_FALSE;
3304 dns_resolver_t *res;
3305 unsigned int bucketnum;
3306 dns_validator_t *validator;
3307 isc_boolean_t destroy = ISC_FALSE;
3309 REQUIRE(VALID_FCTX(fctx));
3314 bucketnum = fctx->bucketnum;
3316 FCTXTRACE("doshutdown");
3319 * An fctx that is shutting down is no longer in ADDRWAIT mode.
3321 fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
3324 * Cancel all pending validators. Note that this must be done
3325 * without the bucket lock held, since that could cause deadlock.
3327 validator = ISC_LIST_HEAD(fctx->validators);
3328 while (validator != NULL) {
3329 dns_validator_cancel(validator);
3330 validator = ISC_LIST_NEXT(validator, link);
3333 if (fctx->nsfetch != NULL)
3334 dns_resolver_cancelfetch(fctx->nsfetch);
3337 * Shut down anything that is still running on behalf of this
3338 * fetch. To avoid deadlock with the ADB, we must do this
3339 * before we lock the bucket lock.
3341 fctx_stopeverything(fctx, ISC_FALSE);
3343 LOCK(&res->buckets[bucketnum].lock);
3345 fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN;
3347 INSIST(fctx->state == fetchstate_active ||
3348 fctx->state == fetchstate_done);
3349 INSIST(fctx->want_shutdown);
3351 if (fctx->state != fetchstate_done) {
3352 fctx->state = fetchstate_done;
3353 fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
3356 if (fctx->references == 0 && fctx->pending == 0 &&
3357 fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
3358 bucket_empty = fctx_unlink(fctx);
3362 UNLOCK(&res->buckets[bucketnum].lock);
3372 fctx_start(isc_task_t *task, isc_event_t *event) {
3373 fetchctx_t *fctx = event->ev_arg;
3374 isc_boolean_t done = ISC_FALSE, bucket_empty = ISC_FALSE;
3375 dns_resolver_t *res;
3376 unsigned int bucketnum;
3377 isc_boolean_t destroy = ISC_FALSE;
3379 REQUIRE(VALID_FCTX(fctx));
3384 bucketnum = fctx->bucketnum;
3388 LOCK(&res->buckets[bucketnum].lock);
3390 INSIST(fctx->state == fetchstate_init);
3391 if (fctx->want_shutdown) {
3393 * We haven't started this fctx yet, and we've been requested
3396 fctx->attributes |= FCTX_ATTR_SHUTTINGDOWN;
3397 fctx->state = fetchstate_done;
3398 fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
3400 * Since we haven't started, we INSIST that we have no
3401 * pending ADB finds and no pending validations.
3403 INSIST(fctx->pending == 0);
3404 INSIST(fctx->nqueries == 0);
3405 INSIST(ISC_LIST_EMPTY(fctx->validators));
3406 if (fctx->references == 0) {
3408 * It's now safe to destroy this fctx.
3410 bucket_empty = fctx_unlink(fctx);
3416 * Normal fctx startup.
3418 fctx->state = fetchstate_active;
3420 * Reset the control event for later use in shutting down
3423 ISC_EVENT_INIT(event, sizeof(*event), 0, NULL,
3424 DNS_EVENT_FETCHCONTROL, fctx_doshutdown, fctx,
3428 UNLOCK(&res->buckets[bucketnum].lock);
3431 isc_result_t result;
3436 * All is well. Start working on the fetch.
3438 result = fctx_starttimer(fctx);
3439 if (result != ISC_R_SUCCESS)
3440 fctx_done(fctx, result, __LINE__);
3442 fctx_try(fctx, ISC_FALSE, ISC_FALSE);
3443 } else if (destroy) {
3451 * Fetch Creation, Joining, and Cancelation.
3454 static inline isc_result_t
3455 fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client,
3456 dns_messageid_t id, isc_taskaction_t action, void *arg,
3457 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
3461 dns_fetchevent_t *event;
3466 * We store the task we're going to send this event to in the
3467 * sender field. We'll make the fetch the sender when we actually
3471 isc_task_attach(task, &clone);
3472 event = (dns_fetchevent_t *)
3473 isc_event_allocate(fctx->res->mctx, clone, DNS_EVENT_FETCHDONE,
3474 action, arg, sizeof(*event));
3475 if (event == NULL) {
3476 isc_task_detach(&clone);
3477 return (ISC_R_NOMEMORY);
3479 event->result = DNS_R_SERVFAIL;
3480 event->qtype = fctx->type;
3483 event->rdataset = rdataset;
3484 event->sigrdataset = sigrdataset;
3485 event->fetch = fetch;
3486 event->client = client;
3488 dns_fixedname_init(&event->foundname);
3491 * Make sure that we can store the sigrdataset in the
3492 * first event if it is needed by any of the events.
3494 if (event->sigrdataset != NULL)
3495 ISC_LIST_PREPEND(fctx->events, event, ev_link);
3497 ISC_LIST_APPEND(fctx->events, event, ev_link);
3499 fctx->client = client;
3501 fetch->magic = DNS_FETCH_MAGIC;
3502 fetch->private = fctx;
3504 return (ISC_R_SUCCESS);
3508 log_ns_ttl(fetchctx_t *fctx, const char *where) {
3509 char namebuf[DNS_NAME_FORMATSIZE];
3510 char domainbuf[DNS_NAME_FORMATSIZE];
3512 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
3513 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
3514 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
3515 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10),
3516 "log_ns_ttl: fctx %p: %s: %s (in '%s'?): %u %u",
3517 fctx, where, namebuf, domainbuf,
3518 fctx->ns_ttl_ok, fctx->ns_ttl);
3522 fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
3523 dns_name_t *domain, dns_rdataset_t *nameservers,
3524 unsigned int options, unsigned int bucketnum, unsigned int depth,
3525 isc_counter_t *qc, fetchctx_t **fctxp)
3528 isc_result_t result;
3529 isc_result_t iresult;
3530 isc_interval_t interval;
3531 dns_fixedname_t fixed;
3532 unsigned int findoptions = 0;
3533 char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
3534 char typebuf[DNS_RDATATYPE_FORMATSIZE];
3539 * Caller must be holding the lock for bucket number 'bucketnum'.
3541 REQUIRE(fctxp != NULL && *fctxp == NULL);
3543 mctx = res->buckets[bucketnum].mctx;
3544 fctx = isc_mem_get(mctx, sizeof(*fctx));
3546 return (ISC_R_NOMEMORY);
3550 isc_counter_attach(qc, &fctx->qc);
3552 result = isc_counter_create(res->mctx,
3553 res->maxqueries, &fctx->qc);
3554 if (result != ISC_R_SUCCESS)
3559 * Make fctx->info point to a copy of a formatted string
3562 dns_name_format(name, buf, sizeof(buf));
3563 dns_rdatatype_format(type, typebuf, sizeof(typebuf));
3564 strcat(buf, "/"); /* checked */
3565 strcat(buf, typebuf); /* checked */
3566 fctx->info = isc_mem_strdup(mctx, buf);
3567 if (fctx->info == NULL) {
3568 result = ISC_R_NOMEMORY;
3569 goto cleanup_counter;
3571 FCTXTRACE("create");
3572 dns_name_init(&fctx->name, NULL);
3573 result = dns_name_dup(name, mctx, &fctx->name);
3574 if (result != ISC_R_SUCCESS)
3576 dns_name_init(&fctx->domain, NULL);
3577 dns_rdataset_init(&fctx->nameservers);
3580 fctx->options = options;
3582 * Note! We do not attach to the task. We are relying on the
3583 * resolver to ensure that this task doesn't go away while we are
3587 fctx->references = 0;
3588 fctx->bucketnum = bucketnum;
3589 fctx->state = fetchstate_init;
3590 fctx->want_shutdown = ISC_FALSE;
3591 fctx->cloned = ISC_FALSE;
3592 fctx->depth = depth;
3593 ISC_LIST_INIT(fctx->queries);
3594 ISC_LIST_INIT(fctx->finds);
3595 ISC_LIST_INIT(fctx->altfinds);
3596 ISC_LIST_INIT(fctx->forwaddrs);
3597 ISC_LIST_INIT(fctx->altaddrs);
3598 ISC_LIST_INIT(fctx->forwarders);
3599 fctx->fwdpolicy = dns_fwdpolicy_none;
3600 ISC_LIST_INIT(fctx->bad);
3601 ISC_LIST_INIT(fctx->edns);
3602 ISC_LIST_INIT(fctx->edns512);
3603 ISC_LIST_INIT(fctx->bad_edns);
3604 ISC_LIST_INIT(fctx->validators);
3605 fctx->validator = NULL;
3607 fctx->altfind = NULL;
3610 fctx->querysent = 0;
3611 fctx->referrals = 0;
3612 TIME_NOW(&fctx->start);
3614 fctx->lamecount = 0;
3620 fctx->result = ISC_R_FAILURE;
3621 fctx->vresult = ISC_R_SUCCESS;
3622 fctx->exitline = -1; /* sentinel */
3623 fctx->logged = ISC_FALSE;
3624 fctx->attributes = 0;
3625 fctx->spilled = ISC_FALSE;
3627 fctx->reason = NULL;
3629 fctx->rand_bits = 0;
3630 fctx->timeout = ISC_FALSE;
3631 fctx->addrinfo = NULL;
3632 fctx->client = NULL;
3634 fctx->ns_ttl_ok = ISC_FALSE;
3636 dns_name_init(&fctx->nsname, NULL);
3637 fctx->nsfetch = NULL;
3638 dns_rdataset_init(&fctx->nsrrset);
3640 if (domain == NULL) {
3641 dns_forwarders_t *forwarders = NULL;
3642 unsigned int labels;
3643 dns_name_t *fwdname = name;
3646 * DS records are found in the parent server.
3647 * Strip label to get the correct forwarder (if any).
3649 if (dns_rdatatype_atparent(fctx->type) &&
3650 dns_name_countlabels(name) > 1) {
3651 dns_name_init(&suffix, NULL);
3652 labels = dns_name_countlabels(name);
3653 dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
3656 dns_fixedname_init(&fixed);
3657 domain = dns_fixedname_name(&fixed);
3658 result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname,
3659 domain, &forwarders);
3660 if (result == ISC_R_SUCCESS)
3661 fctx->fwdpolicy = forwarders->fwdpolicy;
3663 if (fctx->fwdpolicy != dns_fwdpolicy_only) {
3665 * The caller didn't supply a query domain and
3666 * nameservers, and we're not in forward-only mode,
3667 * so find the best nameservers to use.
3669 if (dns_rdatatype_atparent(fctx->type))
3670 findoptions |= DNS_DBFIND_NOEXACT;
3671 result = dns_view_findzonecut(res->view, name, domain,
3672 0, findoptions, ISC_TRUE,
3675 if (result != ISC_R_SUCCESS)
3677 result = dns_name_dup(domain, mctx, &fctx->domain);
3678 if (result != ISC_R_SUCCESS) {
3679 dns_rdataset_disassociate(&fctx->nameservers);
3682 fctx->ns_ttl = fctx->nameservers.ttl;
3683 fctx->ns_ttl_ok = ISC_TRUE;
3686 * We're in forward-only mode. Set the query domain.
3688 result = dns_name_dup(domain, mctx, &fctx->domain);
3689 if (result != ISC_R_SUCCESS)
3693 result = dns_name_dup(domain, mctx, &fctx->domain);
3694 if (result != ISC_R_SUCCESS)
3696 dns_rdataset_clone(nameservers, &fctx->nameservers);
3697 fctx->ns_ttl = fctx->nameservers.ttl;
3698 fctx->ns_ttl_ok = ISC_TRUE;
3701 log_ns_ttl(fctx, "fctx_create");
3703 INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain));
3705 fctx->qmessage = NULL;
3706 result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER,
3709 if (result != ISC_R_SUCCESS)
3710 goto cleanup_domain;
3712 fctx->rmessage = NULL;
3713 result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
3716 if (result != ISC_R_SUCCESS)
3717 goto cleanup_qmessage;
3720 * Compute an expiration time for the entire fetch.
3722 isc_interval_set(&interval, res->query_timeout, 0);
3723 iresult = isc_time_nowplusinterval(&fctx->expires, &interval);
3724 if (iresult != ISC_R_SUCCESS) {
3725 UNEXPECTED_ERROR(__FILE__, __LINE__,
3726 "isc_time_nowplusinterval: %s",
3727 isc_result_totext(iresult));
3728 result = ISC_R_UNEXPECTED;
3729 goto cleanup_rmessage;
3733 * Default retry interval initialization. We set the interval now
3734 * mostly so it won't be uninitialized. It will be set to the
3735 * correct value before a query is issued.
3737 isc_interval_set(&fctx->interval, 2, 0);
3740 * Create an inactive timer. It will be made active when the fetch
3741 * is actually started.
3744 iresult = isc_timer_create(res->timermgr, isc_timertype_inactive,
3746 res->buckets[bucketnum].task, fctx_timeout,
3747 fctx, &fctx->timer);
3748 if (iresult != ISC_R_SUCCESS) {
3749 UNEXPECTED_ERROR(__FILE__, __LINE__,
3750 "isc_timer_create: %s",
3751 isc_result_totext(iresult));
3752 result = ISC_R_UNEXPECTED;
3753 goto cleanup_rmessage;
3757 * Attach to the view's cache and adb.
3760 dns_db_attach(res->view->cachedb, &fctx->cache);
3762 dns_adb_attach(res->view->adb, &fctx->adb);
3764 isc_mem_attach(mctx, &fctx->mctx);
3766 ISC_LIST_INIT(fctx->events);
3767 ISC_LINK_INIT(fctx, link);
3768 fctx->magic = FCTX_MAGIC;
3770 ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link);
3774 UNLOCK(&res->nlock);
3778 return (ISC_R_SUCCESS);
3781 dns_message_destroy(&fctx->rmessage);
3784 dns_message_destroy(&fctx->qmessage);
3787 if (dns_name_countlabels(&fctx->domain) > 0)
3788 dns_name_free(&fctx->domain, mctx);
3789 if (dns_rdataset_isassociated(&fctx->nameservers))
3790 dns_rdataset_disassociate(&fctx->nameservers);
3793 dns_name_free(&fctx->name, mctx);
3796 isc_mem_free(mctx, fctx->info);
3799 isc_counter_detach(&fctx->qc);
3802 isc_mem_put(mctx, fctx, sizeof(*fctx));
3810 static inline isc_boolean_t
3811 is_lame(fetchctx_t *fctx) {
3812 dns_message_t *message = fctx->rmessage;
3814 dns_rdataset_t *rdataset;
3815 isc_result_t result;
3817 if (message->rcode != dns_rcode_noerror &&
3818 message->rcode != dns_rcode_nxdomain)
3821 if (message->counts[DNS_SECTION_ANSWER] != 0)
3824 if (message->counts[DNS_SECTION_AUTHORITY] == 0)
3827 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
3828 while (result == ISC_R_SUCCESS) {
3830 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
3831 for (rdataset = ISC_LIST_HEAD(name->list);
3833 rdataset = ISC_LIST_NEXT(rdataset, link)) {
3834 dns_namereln_t namereln;
3836 unsigned int labels;
3837 if (rdataset->type != dns_rdatatype_ns)
3839 namereln = dns_name_fullcompare(name, &fctx->domain,
3841 if (namereln == dns_namereln_equal &&
3842 (message->flags & DNS_MESSAGEFLAG_AA) != 0)
3844 if (namereln == dns_namereln_subdomain)
3848 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
3855 log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) {
3856 char namebuf[DNS_NAME_FORMATSIZE];
3857 char domainbuf[DNS_NAME_FORMATSIZE];
3858 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
3860 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
3861 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
3862 isc_sockaddr_format(&addrinfo->sockaddr, addrbuf, sizeof(addrbuf));
3863 isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
3864 DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
3865 "lame server resolving '%s' (in '%s'?): %s",
3866 namebuf, domainbuf, addrbuf);
3870 log_formerr(fetchctx_t *fctx, const char *format, ...) {
3871 char nsbuf[ISC_SOCKADDR_FORMATSIZE];
3872 char clbuf[ISC_SOCKADDR_FORMATSIZE];
3873 const char *clmsg = "";
3877 va_start(args, format);
3878 vsnprintf(msgbuf, sizeof(msgbuf), format, args);
3881 isc_sockaddr_format(&fctx->addrinfo->sockaddr, nsbuf, sizeof(nsbuf));
3883 if (fctx->client != NULL) {
3884 clmsg = " for client ";
3885 isc_sockaddr_format(fctx->client, clbuf, sizeof(clbuf));
3890 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
3891 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
3892 "DNS format error from %s resolving %s%s%s: %s",
3893 nsbuf, fctx->info, clmsg, clbuf, msgbuf);
3896 static inline isc_result_t
3897 same_question(fetchctx_t *fctx) {
3898 isc_result_t result;
3899 dns_message_t *message = fctx->rmessage;
3901 dns_rdataset_t *rdataset;
3904 * Caller must be holding the fctx lock.
3908 * XXXRTH Currently we support only one question.
3910 if (message->counts[DNS_SECTION_QUESTION] != 1) {
3911 log_formerr(fctx, "too many questions");
3912 return (DNS_R_FORMERR);
3915 result = dns_message_firstname(message, DNS_SECTION_QUESTION);
3916 if (result != ISC_R_SUCCESS)
3919 dns_message_currentname(message, DNS_SECTION_QUESTION, &name);
3920 rdataset = ISC_LIST_HEAD(name->list);
3921 INSIST(rdataset != NULL);
3922 INSIST(ISC_LIST_NEXT(rdataset, link) == NULL);
3924 if (fctx->type != rdataset->type ||
3925 fctx->res->rdclass != rdataset->rdclass ||
3926 !dns_name_equal(&fctx->name, name)) {
3927 char namebuf[DNS_NAME_FORMATSIZE];
3928 char class[DNS_RDATACLASS_FORMATSIZE];
3929 char type[DNS_RDATATYPE_FORMATSIZE];
3931 dns_name_format(name, namebuf, sizeof(namebuf));
3932 dns_rdataclass_format(rdataset->rdclass, class, sizeof(class));
3933 dns_rdatatype_format(rdataset->type, type, sizeof(type));
3934 log_formerr(fctx, "question section mismatch: got %s/%s/%s",
3935 namebuf, class, type);
3936 return (DNS_R_FORMERR);
3939 return (ISC_R_SUCCESS);
3943 clone_results(fetchctx_t *fctx) {
3944 dns_fetchevent_t *event, *hevent;
3945 isc_result_t result;
3946 dns_name_t *name, *hname;
3948 FCTXTRACE("clone_results");
3951 * Set up any other events to have the same data as the first
3954 * Caller must be holding the appropriate lock.
3957 fctx->cloned = ISC_TRUE;
3958 hevent = ISC_LIST_HEAD(fctx->events);
3961 hname = dns_fixedname_name(&hevent->foundname);
3962 for (event = ISC_LIST_NEXT(hevent, ev_link);
3964 event = ISC_LIST_NEXT(event, ev_link)) {
3965 name = dns_fixedname_name(&event->foundname);
3966 result = dns_name_copy(hname, name, NULL);
3967 if (result != ISC_R_SUCCESS)
3968 event->result = result;
3970 event->result = hevent->result;
3971 dns_db_attach(hevent->db, &event->db);
3972 dns_db_attachnode(hevent->db, hevent->node, &event->node);
3973 INSIST(hevent->rdataset != NULL);
3974 INSIST(event->rdataset != NULL);
3975 if (dns_rdataset_isassociated(hevent->rdataset))
3976 dns_rdataset_clone(hevent->rdataset, event->rdataset);
3977 INSIST(! (hevent->sigrdataset == NULL &&
3978 event->sigrdataset != NULL));
3979 if (hevent->sigrdataset != NULL &&
3980 dns_rdataset_isassociated(hevent->sigrdataset) &&
3981 event->sigrdataset != NULL)
3982 dns_rdataset_clone(hevent->sigrdataset,
3983 event->sigrdataset);
3987 #define CACHE(r) (((r)->attributes & DNS_RDATASETATTR_CACHE) != 0)
3988 #define ANSWER(r) (((r)->attributes & DNS_RDATASETATTR_ANSWER) != 0)
3989 #define ANSWERSIG(r) (((r)->attributes & DNS_RDATASETATTR_ANSWERSIG) != 0)
3990 #define EXTERNAL(r) (((r)->attributes & DNS_RDATASETATTR_EXTERNAL) != 0)
3991 #define CHAINING(r) (((r)->attributes & DNS_RDATASETATTR_CHAINING) != 0)
3992 #define CHASE(r) (((r)->attributes & DNS_RDATASETATTR_CHASE) != 0)
3993 #define CHECKNAMES(r) (((r)->attributes & DNS_RDATASETATTR_CHECKNAMES) != 0)
3997 * Destroy '*fctx' if it is ready to be destroyed (i.e., if it has
3998 * no references and is no longer waiting for any events).
4001 * '*fctx' is shutting down.
4004 * true if the resolver is exiting and this is the last fctx in the bucket.
4006 static isc_boolean_t
4007 maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
4008 unsigned int bucketnum;
4009 isc_boolean_t bucket_empty = ISC_FALSE;
4010 dns_resolver_t *res = fctx->res;
4011 dns_validator_t *validator, *next_validator;
4012 isc_boolean_t destroy = ISC_FALSE;
4014 REQUIRE(SHUTTINGDOWN(fctx));
4016 bucketnum = fctx->bucketnum;
4018 LOCK(&res->buckets[bucketnum].lock);
4019 if (fctx->pending != 0 || fctx->nqueries != 0)
4022 for (validator = ISC_LIST_HEAD(fctx->validators);
4023 validator != NULL; validator = next_validator) {
4024 next_validator = ISC_LIST_NEXT(validator, link);
4025 dns_validator_cancel(validator);
4028 if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) {
4029 bucket_empty = fctx_unlink(fctx);
4034 UNLOCK(&res->buckets[bucketnum].lock);
4037 return (bucket_empty);
4041 * The validator has finished.
4044 validated(isc_task_t *task, isc_event_t *event) {
4045 dns_adbaddrinfo_t *addrinfo;
4046 dns_dbnode_t *node = NULL;
4047 dns_dbnode_t *nsnode = NULL;
4048 dns_fetchevent_t *hevent;
4050 dns_rdataset_t *ardataset = NULL;
4051 dns_rdataset_t *asigrdataset = NULL;
4052 dns_rdataset_t *rdataset;
4053 dns_rdataset_t *sigrdataset;
4054 dns_resolver_t *res;
4055 dns_valarg_t *valarg;
4056 dns_validatorevent_t *vevent;
4058 isc_boolean_t chaining;
4059 isc_boolean_t negative;
4060 isc_boolean_t sentresponse;
4061 isc_result_t eresult = ISC_R_SUCCESS;
4062 isc_result_t result = ISC_R_SUCCESS;
4066 UNUSED(task); /* for now */
4068 REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
4069 valarg = event->ev_arg;
4070 fctx = valarg->fctx;
4072 addrinfo = valarg->addrinfo;
4073 REQUIRE(VALID_FCTX(fctx));
4074 REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
4076 vevent = (dns_validatorevent_t *)event;
4077 fctx->vresult = vevent->result;
4079 FCTXTRACE("received validation completion event");
4081 LOCK(&res->buckets[fctx->bucketnum].lock);
4083 ISC_LIST_UNLINK(fctx->validators, vevent->validator, link);
4084 fctx->validator = NULL;
4087 * Destroy the validator early so that we can
4088 * destroy the fctx if necessary.
4090 dns_validator_destroy(&vevent->validator);
4091 isc_mem_put(fctx->mctx, valarg, sizeof(*valarg));
4093 negative = ISC_TF(vevent->rdataset == NULL);
4095 sentresponse = ISC_TF((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0);
4098 * If shutting down, ignore the results. Check to see if we're
4099 * done waiting for validator completions and ADB pending events; if
4100 * so, destroy the fctx.
4102 if (SHUTTINGDOWN(fctx) && !sentresponse) {
4103 isc_uint32_t bucketnum = fctx->bucketnum;
4104 isc_boolean_t bucket_empty;
4105 bucket_empty = maybe_destroy(fctx, ISC_TRUE);
4106 UNLOCK(&res->buckets[bucketnum].lock);
4112 isc_stdtime_get(&now);
4115 * If chaining, we need to make sure that the right result code is
4116 * returned, and that the rdatasets are bound.
4118 if (vevent->result == ISC_R_SUCCESS &&
4120 vevent->rdataset != NULL &&
4121 CHAINING(vevent->rdataset))
4123 if (vevent->rdataset->type == dns_rdatatype_cname)
4124 eresult = DNS_R_CNAME;
4126 INSIST(vevent->rdataset->type == dns_rdatatype_dname);
4127 eresult = DNS_R_DNAME;
4129 chaining = ISC_TRUE;
4131 chaining = ISC_FALSE;
4134 * Either we're not shutting down, or we are shutting down but want
4135 * to cache the result anyway (if this was a validation started by
4136 * a query with cd set)
4139 hevent = ISC_LIST_HEAD(fctx->events);
4140 if (hevent != NULL) {
4141 if (!negative && !chaining &&
4142 (fctx->type == dns_rdatatype_any ||
4143 fctx->type == dns_rdatatype_rrsig ||
4144 fctx->type == dns_rdatatype_sig)) {
4146 * Don't bind rdatasets; the caller
4147 * will iterate the node.
4150 ardataset = hevent->rdataset;
4151 asigrdataset = hevent->sigrdataset;
4155 if (vevent->result != ISC_R_SUCCESS) {
4156 FCTXTRACE("validation failed");
4157 inc_stats(res, dns_resstatscounter_valfail);
4159 fctx->vresult = vevent->result;
4160 if (fctx->vresult != DNS_R_BROKENCHAIN) {
4161 result = ISC_R_NOTFOUND;
4162 if (vevent->rdataset != NULL)
4163 result = dns_db_findnode(fctx->cache,
4166 if (result == ISC_R_SUCCESS)
4167 (void)dns_db_deleterdataset(fctx->cache, node,
4170 if (result == ISC_R_SUCCESS &&
4171 vevent->sigrdataset != NULL)
4172 (void)dns_db_deleterdataset(fctx->cache, node,
4174 dns_rdatatype_rrsig,
4176 if (result == ISC_R_SUCCESS)
4177 dns_db_detachnode(fctx->cache, &node);
4179 if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) {
4181 * Cache the data as pending for later validation.
4183 result = ISC_R_NOTFOUND;
4184 if (vevent->rdataset != NULL)
4185 result = dns_db_findnode(fctx->cache,
4188 if (result == ISC_R_SUCCESS) {
4189 (void)dns_db_addrdataset(fctx->cache, node,
4191 vevent->rdataset, 0,
4194 if (result == ISC_R_SUCCESS &&
4195 vevent->sigrdataset != NULL)
4196 (void)dns_db_addrdataset(fctx->cache, node,
4198 vevent->sigrdataset,
4200 if (result == ISC_R_SUCCESS)
4201 dns_db_detachnode(fctx->cache, &node);
4203 result = fctx->vresult;
4204 add_bad(fctx, addrinfo, result, badns_validation);
4205 isc_event_free(&event);
4206 UNLOCK(&res->buckets[fctx->bucketnum].lock);
4207 INSIST(fctx->validator == NULL);
4208 fctx->validator = ISC_LIST_HEAD(fctx->validators);
4209 if (fctx->validator != NULL)
4210 dns_validator_send(fctx->validator);
4211 else if (sentresponse)
4212 fctx_done(fctx, result, __LINE__); /* Locks bucket. */
4213 else if (result == DNS_R_BROKENCHAIN) {
4214 isc_result_t tresult;
4218 isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
4219 tresult = isc_time_nowplusinterval(&expire, &i);
4221 (fctx->type == dns_rdatatype_dnskey ||
4222 fctx->type == dns_rdatatype_dlv ||
4223 fctx->type == dns_rdatatype_ds) &&
4224 tresult == ISC_R_SUCCESS)
4225 dns_resolver_addbadcache(res, &fctx->name,
4226 fctx->type, &expire);
4227 fctx_done(fctx, result, __LINE__); /* Locks bucket. */
4229 fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */
4235 dns_rdatatype_t covers;
4236 FCTXTRACE("nonexistence validation OK");
4238 inc_stats(res, dns_resstatscounter_valnegsuccess);
4240 if (fctx->rmessage->rcode == dns_rcode_nxdomain)
4241 covers = dns_rdatatype_any;
4243 covers = fctx->type;
4245 result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE,
4247 if (result != ISC_R_SUCCESS)
4248 goto noanswer_response;
4251 * If we are asking for a SOA record set the cache time
4252 * to zero to facilitate locating the containing zone of
4255 ttl = res->view->maxncachettl;
4256 if (fctx->type == dns_rdatatype_soa &&
4257 covers == dns_rdatatype_any && res->zero_no_soa_ttl)
4260 result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
4261 covers, now, ttl, vevent->optout,
4262 ardataset, &eresult);
4263 if (result != ISC_R_SUCCESS)
4264 goto noanswer_response;
4265 goto answer_response;
4267 inc_stats(res, dns_resstatscounter_valsuccess);
4269 FCTXTRACE("validation OK");
4271 if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
4273 result = dns_rdataset_addnoqname(vevent->rdataset,
4274 vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]);
4275 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4276 INSIST(vevent->sigrdataset != NULL);
4277 vevent->sigrdataset->ttl = vevent->rdataset->ttl;
4278 if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) {
4279 result = dns_rdataset_addclosest(vevent->rdataset,
4280 vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]);
4281 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4286 * The data was already cached as pending data.
4287 * Re-cache it as secure and bind the cached
4288 * rdatasets to the first event on the fetch
4291 result = dns_db_findnode(fctx->cache, vevent->name, ISC_TRUE, &node);
4292 if (result != ISC_R_SUCCESS)
4293 goto noanswer_response;
4295 result = dns_db_addrdataset(fctx->cache, node, NULL, now,
4296 vevent->rdataset, 0, ardataset);
4297 if (result != ISC_R_SUCCESS &&
4298 result != DNS_R_UNCHANGED)
4299 goto noanswer_response;
4300 if (ardataset != NULL && NEGATIVE(ardataset)) {
4301 if (NXDOMAIN(ardataset))
4302 eresult = DNS_R_NCACHENXDOMAIN;
4304 eresult = DNS_R_NCACHENXRRSET;
4305 } else if (vevent->sigrdataset != NULL) {
4306 result = dns_db_addrdataset(fctx->cache, node, NULL, now,
4307 vevent->sigrdataset, 0,
4309 if (result != ISC_R_SUCCESS &&
4310 result != DNS_R_UNCHANGED)
4311 goto noanswer_response;
4315 isc_boolean_t bucket_empty = ISC_FALSE;
4317 * If we only deferred the destroy because we wanted to cache
4318 * the data, destroy now.
4320 dns_db_detachnode(fctx->cache, &node);
4321 if (SHUTTINGDOWN(fctx))
4322 bucket_empty = maybe_destroy(fctx, ISC_TRUE);
4323 UNLOCK(&res->buckets[fctx->bucketnum].lock);
4329 if (!ISC_LIST_EMPTY(fctx->validators)) {
4331 INSIST(fctx->type == dns_rdatatype_any ||
4332 fctx->type == dns_rdatatype_rrsig ||
4333 fctx->type == dns_rdatatype_sig);
4335 * Don't send a response yet - we have
4336 * more rdatasets that still need to
4339 dns_db_detachnode(fctx->cache, &node);
4340 UNLOCK(&res->buckets[fctx->bucketnum].lock);
4341 dns_validator_send(ISC_LIST_HEAD(fctx->validators));
4347 * Cache any NS/NSEC records that happened to be validated.
4349 result = dns_message_firstname(fctx->rmessage, DNS_SECTION_AUTHORITY);
4350 while (result == ISC_R_SUCCESS) {
4352 dns_message_currentname(fctx->rmessage, DNS_SECTION_AUTHORITY,
4354 for (rdataset = ISC_LIST_HEAD(name->list);
4356 rdataset = ISC_LIST_NEXT(rdataset, link)) {
4357 if ((rdataset->type != dns_rdatatype_ns &&
4358 rdataset->type != dns_rdatatype_nsec) ||
4359 rdataset->trust != dns_trust_secure)
4361 for (sigrdataset = ISC_LIST_HEAD(name->list);
4362 sigrdataset != NULL;
4363 sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
4364 if (sigrdataset->type != dns_rdatatype_rrsig ||
4365 sigrdataset->covers != rdataset->type)
4369 if (sigrdataset == NULL ||
4370 sigrdataset->trust != dns_trust_secure)
4372 result = dns_db_findnode(fctx->cache, name, ISC_TRUE,
4374 if (result != ISC_R_SUCCESS)
4377 result = dns_db_addrdataset(fctx->cache, nsnode, NULL,
4378 now, rdataset, 0, NULL);
4379 if (result == ISC_R_SUCCESS)
4380 result = dns_db_addrdataset(fctx->cache, nsnode,
4384 dns_db_detachnode(fctx->cache, &nsnode);
4385 if (result != ISC_R_SUCCESS)
4388 result = dns_message_nextname(fctx->rmessage,
4389 DNS_SECTION_AUTHORITY);
4392 result = ISC_R_SUCCESS;
4395 * Respond with an answer, positive or negative,
4396 * as opposed to an error. 'node' must be non-NULL.
4399 fctx->attributes |= FCTX_ATTR_HAVEANSWER;
4401 if (hevent != NULL) {
4402 hevent->result = eresult;
4403 RUNTIME_CHECK(dns_name_copy(vevent->name,
4404 dns_fixedname_name(&hevent->foundname), NULL)
4406 dns_db_attach(fctx->cache, &hevent->db);
4407 dns_db_transfernode(fctx->cache, &node, &hevent->node);
4408 clone_results(fctx);
4413 dns_db_detachnode(fctx->cache, &node);
4415 UNLOCK(&res->buckets[fctx->bucketnum].lock);
4416 fctx_done(fctx, result, __LINE__); /* Locks bucket. */
4419 INSIST(node == NULL);
4420 isc_event_free(&event);
4423 static inline isc_result_t
4424 cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
4427 dns_rdataset_t *rdataset, *sigrdataset;
4428 dns_rdataset_t *addedrdataset, *ardataset, *asigrdataset;
4429 dns_rdataset_t *valrdataset = NULL, *valsigrdataset = NULL;
4430 dns_dbnode_t *node, **anodep;
4433 dns_resolver_t *res;
4434 isc_boolean_t need_validation, secure_domain, have_answer;
4435 isc_result_t result, eresult;
4436 dns_fetchevent_t *event;
4437 unsigned int options;
4440 unsigned int valoptions = 0;
4443 * The appropriate bucket lock must be held.
4447 need_validation = ISC_FALSE;
4448 POST(need_validation);
4449 secure_domain = ISC_FALSE;
4450 have_answer = ISC_FALSE;
4451 eresult = ISC_R_SUCCESS;
4452 task = res->buckets[fctx->bucketnum].task;
4455 * Is DNSSEC validation required for this name?
4457 if (res->view->enablevalidation) {
4458 result = dns_view_issecuredomain(res->view, name,
4460 if (result != ISC_R_SUCCESS)
4463 if (!secure_domain && res->view->dlv != NULL) {
4464 valoptions = DNS_VALIDATOR_DLV;
4465 secure_domain = ISC_TRUE;
4469 if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
4470 need_validation = ISC_FALSE;
4472 need_validation = secure_domain;
4478 asigrdataset = NULL;
4480 if ((name->attributes & DNS_NAMEATTR_ANSWER) != 0 &&
4482 have_answer = ISC_TRUE;
4483 event = ISC_LIST_HEAD(fctx->events);
4484 if (event != NULL) {
4486 aname = dns_fixedname_name(&event->foundname);
4487 result = dns_name_copy(name, aname, NULL);
4488 if (result != ISC_R_SUCCESS)
4490 anodep = &event->node;
4492 * If this is an ANY, SIG or RRSIG query, we're not
4493 * going to return any rdatasets, unless we encountered
4494 * a CNAME or DNAME as "the answer". In this case,
4495 * we're going to return DNS_R_CNAME or DNS_R_DNAME
4496 * and we must set up the rdatasets.
4498 if ((fctx->type != dns_rdatatype_any &&
4499 fctx->type != dns_rdatatype_rrsig &&
4500 fctx->type != dns_rdatatype_sig) ||
4501 (name->attributes & DNS_NAMEATTR_CHAINING) != 0) {
4502 ardataset = event->rdataset;
4503 asigrdataset = event->sigrdataset;
4509 * Find or create the cache node.
4512 result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node);
4513 if (result != ISC_R_SUCCESS)
4517 * Cache or validate each cacheable rdataset.
4519 fail = ISC_TF((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0);
4520 for (rdataset = ISC_LIST_HEAD(name->list);
4522 rdataset = ISC_LIST_NEXT(rdataset, link)) {
4523 if (!CACHE(rdataset))
4525 if (CHECKNAMES(rdataset)) {
4526 char namebuf[DNS_NAME_FORMATSIZE];
4527 char typebuf[DNS_RDATATYPE_FORMATSIZE];
4528 char classbuf[DNS_RDATATYPE_FORMATSIZE];
4530 dns_name_format(name, namebuf, sizeof(namebuf));
4531 dns_rdatatype_format(rdataset->type, typebuf,
4533 dns_rdataclass_format(rdataset->rdclass, classbuf,
4535 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
4536 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
4537 "check-names %s %s/%s/%s",
4538 fail ? "failure" : "warning",
4539 namebuf, typebuf, classbuf);
4541 if (ANSWER(rdataset)) {
4542 dns_db_detachnode(fctx->cache, &node);
4543 return (DNS_R_BADNAME);
4550 * Enforce the configure maximum cache TTL.
4552 if (rdataset->ttl > res->view->maxcachettl)
4553 rdataset->ttl = res->view->maxcachettl;
4556 * If this RRset is in a secure domain, is in bailiwick,
4557 * and is not glue, attempt DNSSEC validation. (We do not
4558 * attempt to validate glue or out-of-bailiwick data--even
4559 * though there might be some performance benefit to doing
4560 * so--because it makes it simpler and safer to ensure that
4561 * records from a secure domain are only cached if validated
4562 * within the context of a query to the domain that owns
4565 if (secure_domain && rdataset->trust != dns_trust_glue &&
4566 !EXTERNAL(rdataset)) {
4570 * RRSIGs are validated as part of validating the
4573 if (rdataset->type == dns_rdatatype_rrsig)
4576 * Find the SIG for this rdataset, if we have it.
4578 for (sigrdataset = ISC_LIST_HEAD(name->list);
4579 sigrdataset != NULL;
4580 sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
4581 if (sigrdataset->type == dns_rdatatype_rrsig &&
4582 sigrdataset->covers == rdataset->type)
4585 if (sigrdataset == NULL) {
4586 if (!ANSWER(rdataset) && need_validation) {
4588 * Ignore non-answer rdatasets that
4589 * are missing signatures.
4596 * Normalize the rdataset and sigrdataset TTLs.
4598 if (sigrdataset != NULL) {
4599 rdataset->ttl = ISC_MIN(rdataset->ttl,
4601 sigrdataset->ttl = rdataset->ttl;
4605 * Cache this rdataset/sigrdataset pair as
4606 * pending data. Track whether it was additional
4609 if (rdataset->trust == dns_trust_additional)
4610 trust = dns_trust_pending_additional;
4612 trust = dns_trust_pending_answer;
4614 rdataset->trust = trust;
4615 if (sigrdataset != NULL)
4616 sigrdataset->trust = trust;
4617 if (!need_validation || !ANSWER(rdataset)) {
4618 addedrdataset = ardataset;
4619 result = dns_db_addrdataset(fctx->cache, node,
4620 NULL, now, rdataset,
4622 if (result == DNS_R_UNCHANGED) {
4623 result = ISC_R_SUCCESS;
4624 if (!need_validation &&
4625 ardataset != NULL &&
4626 NEGATIVE(ardataset)) {
4628 * The answer in the cache is
4629 * better than the answer we
4630 * found, and is a negative
4631 * cache entry, so we must set
4632 * eresult appropriately.
4634 if (NXDOMAIN(ardataset))
4636 DNS_R_NCACHENXDOMAIN;
4639 DNS_R_NCACHENXRRSET;
4641 * We have a negative response
4642 * from the cache so don't
4643 * attempt to add the RRSIG
4649 if (result != ISC_R_SUCCESS)
4651 if (sigrdataset != NULL) {
4652 addedrdataset = asigrdataset;
4653 result = dns_db_addrdataset(fctx->cache,
4657 if (result == DNS_R_UNCHANGED)
4658 result = ISC_R_SUCCESS;
4659 if (result != ISC_R_SUCCESS)
4661 } else if (!ANSWER(rdataset))
4665 if (ANSWER(rdataset) && need_validation) {
4666 if (fctx->type != dns_rdatatype_any &&
4667 fctx->type != dns_rdatatype_rrsig &&
4668 fctx->type != dns_rdatatype_sig) {
4670 * This is The Answer. We will
4671 * validate it, but first we cache
4672 * the rest of the response - it may
4673 * contain useful keys.
4675 INSIST(valrdataset == NULL &&
4676 valsigrdataset == NULL);
4677 valrdataset = rdataset;
4678 valsigrdataset = sigrdataset;
4681 * This is one of (potentially)
4682 * multiple answers to an ANY
4683 * or SIG query. To keep things
4684 * simple, we just start the
4685 * validator right away rather
4686 * than caching first and
4687 * having to remember which
4688 * rdatasets needed validation.
4690 result = valcreate(fctx, addrinfo,
4691 name, rdataset->type,
4696 * Defer any further validations.
4697 * This prevents multiple validators
4698 * from manipulating fctx->rmessage
4701 valoptions |= DNS_VALIDATOR_DEFER;
4703 } else if (CHAINING(rdataset)) {
4704 if (rdataset->type == dns_rdatatype_cname)
4705 eresult = DNS_R_CNAME;
4707 INSIST(rdataset->type ==
4708 dns_rdatatype_dname);
4709 eresult = DNS_R_DNAME;
4712 } else if (!EXTERNAL(rdataset)) {
4714 * It's OK to cache this rdataset now.
4716 if (ANSWER(rdataset))
4717 addedrdataset = ardataset;
4718 else if (ANSWERSIG(rdataset))
4719 addedrdataset = asigrdataset;
4721 addedrdataset = NULL;
4722 if (CHAINING(rdataset)) {
4723 if (rdataset->type == dns_rdatatype_cname)
4724 eresult = DNS_R_CNAME;
4726 INSIST(rdataset->type ==
4727 dns_rdatatype_dname);
4728 eresult = DNS_R_DNAME;
4731 if (rdataset->trust == dns_trust_glue &&
4732 (rdataset->type == dns_rdatatype_ns ||
4733 (rdataset->type == dns_rdatatype_rrsig &&
4734 rdataset->covers == dns_rdatatype_ns))) {
4736 * If the trust level is 'dns_trust_glue'
4737 * then we are adding data from a referral
4738 * we got while executing the search algorithm.
4739 * New referral data always takes precedence
4740 * over the existing cache contents.
4742 options = DNS_DBADD_FORCE;
4746 * Now we can add the rdataset.
4748 result = dns_db_addrdataset(fctx->cache,
4753 if (result == DNS_R_UNCHANGED) {
4754 if (ANSWER(rdataset) &&
4755 ardataset != NULL &&
4756 NEGATIVE(ardataset)) {
4758 * The answer in the cache is better
4759 * than the answer we found, and is
4760 * a negative cache entry, so we
4761 * must set eresult appropriately.
4763 if (NXDOMAIN(ardataset))
4764 eresult = DNS_R_NCACHENXDOMAIN;
4766 eresult = DNS_R_NCACHENXRRSET;
4768 result = ISC_R_SUCCESS;
4769 } else if (result != ISC_R_SUCCESS)
4774 if (valrdataset != NULL)
4775 result = valcreate(fctx, addrinfo, name, fctx->type,
4776 valrdataset, valsigrdataset, valoptions,
4779 if (result == ISC_R_SUCCESS && have_answer) {
4780 fctx->attributes |= FCTX_ATTR_HAVEANSWER;
4781 if (event != NULL) {
4783 * Negative results must be indicated in event->result.
4785 if (dns_rdataset_isassociated(event->rdataset) &&
4786 NEGATIVE(event->rdataset)) {
4787 INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
4788 eresult == DNS_R_NCACHENXRRSET);
4790 event->result = eresult;
4791 dns_db_attach(fctx->cache, adbp);
4792 dns_db_transfernode(fctx->cache, &node, anodep);
4793 clone_results(fctx);
4798 dns_db_detachnode(fctx->cache, &node);
4803 static inline isc_result_t
4804 cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
4806 isc_result_t result;
4807 dns_section_t section;
4810 FCTXTRACE("cache_message");
4812 fctx->attributes &= ~FCTX_ATTR_WANTCACHE;
4814 LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
4816 for (section = DNS_SECTION_ANSWER;
4817 section <= DNS_SECTION_ADDITIONAL;
4819 result = dns_message_firstname(fctx->rmessage, section);
4820 while (result == ISC_R_SUCCESS) {
4822 dns_message_currentname(fctx->rmessage, section,
4824 if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) {
4825 result = cache_name(fctx, name, addrinfo, now);
4826 if (result != ISC_R_SUCCESS)
4829 result = dns_message_nextname(fctx->rmessage, section);
4831 if (result != ISC_R_NOMORE)
4834 if (result == ISC_R_NOMORE)
4835 result = ISC_R_SUCCESS;
4837 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
4843 * Do what dns_ncache_addoptout() does, and then compute an appropriate eresult.
4846 ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
4847 dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
4848 isc_boolean_t optout, dns_rdataset_t *ardataset,
4849 isc_result_t *eresultp)
4851 isc_result_t result;
4852 dns_rdataset_t rdataset;
4854 if (ardataset == NULL) {
4855 dns_rdataset_init(&rdataset);
4856 ardataset = &rdataset;
4858 result = dns_ncache_addoptout(message, cache, node, covers, now,
4859 maxttl, optout, ardataset);
4860 if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) {
4862 * If the cache now contains a negative entry and we
4863 * care about whether it is DNS_R_NCACHENXDOMAIN or
4864 * DNS_R_NCACHENXRRSET then extract it.
4866 if (NEGATIVE(ardataset)) {
4868 * The cache data is a negative cache entry.
4870 if (NXDOMAIN(ardataset))
4871 *eresultp = DNS_R_NCACHENXDOMAIN;
4873 *eresultp = DNS_R_NCACHENXRRSET;
4876 * Either we don't care about the nature of the
4877 * cache rdataset (because no fetch is interested
4878 * in the outcome), or the cache rdataset is not
4879 * a negative cache entry. Whichever case it is,
4880 * we can return success.
4882 * XXXRTH There's a CNAME/DNAME problem here.
4884 *eresultp = ISC_R_SUCCESS;
4886 result = ISC_R_SUCCESS;
4888 if (ardataset == &rdataset && dns_rdataset_isassociated(ardataset))
4889 dns_rdataset_disassociate(ardataset);
4894 static inline isc_result_t
4895 ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
4896 dns_rdatatype_t covers, isc_stdtime_t now)
4898 isc_result_t result, eresult;
4900 dns_resolver_t *res;
4902 dns_dbnode_t *node, **anodep;
4903 dns_rdataset_t *ardataset;
4904 isc_boolean_t need_validation, secure_domain;
4906 dns_fetchevent_t *event;
4908 unsigned int valoptions = 0;
4910 FCTXTRACE("ncache_message");
4912 fctx->attributes &= ~FCTX_ATTR_WANTNCACHE;
4915 need_validation = ISC_FALSE;
4916 POST(need_validation);
4917 secure_domain = ISC_FALSE;
4918 eresult = ISC_R_SUCCESS;
4923 * XXXMPA remove when we follow cnames and adjust the setting
4924 * of FCTX_ATTR_WANTNCACHE in noanswer_response().
4926 INSIST(fctx->rmessage->counts[DNS_SECTION_ANSWER] == 0);
4929 * Is DNSSEC validation required for this name?
4931 if (fctx->res->view->enablevalidation) {
4932 result = dns_view_issecuredomain(res->view, name,
4934 if (result != ISC_R_SUCCESS)
4937 if (!secure_domain && res->view->dlv != NULL) {
4938 valoptions = DNS_VALIDATOR_DLV;
4939 secure_domain = ISC_TRUE;
4943 if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
4944 need_validation = ISC_FALSE;
4946 need_validation = secure_domain;
4948 if (secure_domain) {
4950 * Mark all rdatasets as pending.
4952 dns_rdataset_t *trdataset;
4955 result = dns_message_firstname(fctx->rmessage,
4956 DNS_SECTION_AUTHORITY);
4957 while (result == ISC_R_SUCCESS) {
4959 dns_message_currentname(fctx->rmessage,
4960 DNS_SECTION_AUTHORITY,
4962 for (trdataset = ISC_LIST_HEAD(tname->list);
4964 trdataset = ISC_LIST_NEXT(trdataset, link))
4965 trdataset->trust = dns_trust_pending_answer;
4966 result = dns_message_nextname(fctx->rmessage,
4967 DNS_SECTION_AUTHORITY);
4969 if (result != ISC_R_NOMORE)
4974 if (need_validation) {
4976 * Do negative response validation.
4978 result = valcreate(fctx, addrinfo, name, fctx->type,
4979 NULL, NULL, valoptions,
4980 res->buckets[fctx->bucketnum].task);
4982 * If validation is necessary, return now. Otherwise continue
4983 * to process the message, letting the validation complete
4984 * in its own good time.
4989 LOCK(&res->buckets[fctx->bucketnum].lock);
4995 if (!HAVE_ANSWER(fctx)) {
4996 event = ISC_LIST_HEAD(fctx->events);
4997 if (event != NULL) {
4999 aname = dns_fixedname_name(&event->foundname);
5000 result = dns_name_copy(name, aname, NULL);
5001 if (result != ISC_R_SUCCESS)
5003 anodep = &event->node;
5004 ardataset = event->rdataset;
5009 result = dns_db_findnode(fctx->cache, name, ISC_TRUE, &node);
5010 if (result != ISC_R_SUCCESS)
5014 * If we are asking for a SOA record set the cache time
5015 * to zero to facilitate locating the containing zone of
5018 ttl = fctx->res->view->maxncachettl;
5019 if (fctx->type == dns_rdatatype_soa &&
5020 covers == dns_rdatatype_any &&
5021 fctx->res->zero_no_soa_ttl)
5024 result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
5025 covers, now, ttl, ISC_FALSE,
5026 ardataset, &eresult);
5027 if (result != ISC_R_SUCCESS)
5030 if (!HAVE_ANSWER(fctx)) {
5031 fctx->attributes |= FCTX_ATTR_HAVEANSWER;
5032 if (event != NULL) {
5033 event->result = eresult;
5034 dns_db_attach(fctx->cache, adbp);
5035 dns_db_transfernode(fctx->cache, &node, anodep);
5036 clone_results(fctx);
5041 UNLOCK(&res->buckets[fctx->bucketnum].lock);
5044 dns_db_detachnode(fctx->cache, &node);
5050 mark_related(dns_name_t *name, dns_rdataset_t *rdataset,
5051 isc_boolean_t external, isc_boolean_t gluing)
5053 name->attributes |= DNS_NAMEATTR_CACHE;
5055 rdataset->trust = dns_trust_glue;
5057 * Glue with 0 TTL causes problems. We force the TTL to
5058 * 1 second to prevent this.
5060 if (rdataset->ttl == 0)
5063 rdataset->trust = dns_trust_additional;
5065 * Avoid infinite loops by only marking new rdatasets.
5067 if (!CACHE(rdataset)) {
5068 name->attributes |= DNS_NAMEATTR_CHASE;
5069 rdataset->attributes |= DNS_RDATASETATTR_CHASE;
5071 rdataset->attributes |= DNS_RDATASETATTR_CACHE;
5073 rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL;
5077 check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type,
5078 dns_section_t section)
5080 fetchctx_t *fctx = arg;
5081 isc_result_t result;
5083 dns_rdataset_t *rdataset;
5084 isc_boolean_t external;
5085 dns_rdatatype_t rtype;
5086 isc_boolean_t gluing;
5088 REQUIRE(VALID_FCTX(fctx));
5090 #if CHECK_FOR_GLUE_IN_ANSWER
5091 if (section == DNS_SECTION_ANSWER && type != dns_rdatatype_a)
5092 return (ISC_R_SUCCESS);
5101 result = dns_message_findname(fctx->rmessage, section, addname,
5102 dns_rdatatype_any, 0, &name, NULL);
5103 if (result == ISC_R_SUCCESS) {
5104 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
5105 if (type == dns_rdatatype_a) {
5106 for (rdataset = ISC_LIST_HEAD(name->list);
5108 rdataset = ISC_LIST_NEXT(rdataset, link)) {
5109 if (rdataset->type == dns_rdatatype_rrsig)
5110 rtype = rdataset->covers;
5112 rtype = rdataset->type;
5113 if (rtype == dns_rdatatype_a ||
5114 rtype == dns_rdatatype_aaaa)
5115 mark_related(name, rdataset, external,
5119 result = dns_message_findtype(name, type, 0,
5121 if (result == ISC_R_SUCCESS) {
5122 mark_related(name, rdataset, external, gluing);
5124 * Do we have its SIG too?
5127 result = dns_message_findtype(name,
5128 dns_rdatatype_rrsig,
5130 if (result == ISC_R_SUCCESS)
5131 mark_related(name, rdataset, external,
5137 return (ISC_R_SUCCESS);
5141 check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
5142 return (check_section(arg, addname, type, DNS_SECTION_ADDITIONAL));
5145 #ifndef CHECK_FOR_GLUE_IN_ANSWER
5146 #define CHECK_FOR_GLUE_IN_ANSWER 0
5148 #if CHECK_FOR_GLUE_IN_ANSWER
5150 check_answer(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
5151 return (check_section(arg, addname, type, DNS_SECTION_ANSWER));
5156 chase_additional(fetchctx_t *fctx) {
5157 isc_boolean_t rescan;
5158 dns_section_t section = DNS_SECTION_ADDITIONAL;
5159 isc_result_t result;
5164 for (result = dns_message_firstname(fctx->rmessage, section);
5165 result == ISC_R_SUCCESS;
5166 result = dns_message_nextname(fctx->rmessage, section)) {
5167 dns_name_t *name = NULL;
5168 dns_rdataset_t *rdataset;
5169 dns_message_currentname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
5171 if ((name->attributes & DNS_NAMEATTR_CHASE) == 0)
5173 name->attributes &= ~DNS_NAMEATTR_CHASE;
5174 for (rdataset = ISC_LIST_HEAD(name->list);
5176 rdataset = ISC_LIST_NEXT(rdataset, link)) {
5177 if (CHASE(rdataset)) {
5178 rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
5179 (void)dns_rdataset_additionaldata(rdataset,
5190 static inline isc_result_t
5191 cname_target(dns_rdataset_t *rdataset, dns_name_t *tname) {
5192 isc_result_t result;
5193 dns_rdata_t rdata = DNS_RDATA_INIT;
5194 dns_rdata_cname_t cname;
5196 result = dns_rdataset_first(rdataset);
5197 if (result != ISC_R_SUCCESS)
5199 dns_rdataset_current(rdataset, &rdata);
5200 result = dns_rdata_tostruct(&rdata, &cname, NULL);
5201 if (result != ISC_R_SUCCESS)
5203 dns_name_init(tname, NULL);
5204 dns_name_clone(&cname.cname, tname);
5205 dns_rdata_freestruct(&cname);
5207 return (ISC_R_SUCCESS);
5210 static inline isc_result_t
5211 dname_target(fetchctx_t *fctx, dns_rdataset_t *rdataset, dns_name_t *qname,
5212 dns_name_t *oname, dns_fixedname_t *fixeddname)
5214 isc_result_t result;
5215 dns_rdata_t rdata = DNS_RDATA_INIT;
5216 unsigned int nlabels;
5218 dns_namereln_t namereln;
5219 dns_rdata_dname_t dname;
5220 dns_fixedname_t prefix;
5223 * Get the target name of the DNAME.
5225 result = dns_rdataset_first(rdataset);
5226 if (result != ISC_R_SUCCESS)
5228 dns_rdataset_current(rdataset, &rdata);
5229 result = dns_rdata_tostruct(&rdata, &dname, NULL);
5230 if (result != ISC_R_SUCCESS)
5234 * Get the prefix of qname.
5236 namereln = dns_name_fullcompare(qname, oname, &order, &nlabels);
5237 if (namereln != dns_namereln_subdomain) {
5238 char qbuf[DNS_NAME_FORMATSIZE];
5239 char obuf[DNS_NAME_FORMATSIZE];
5241 dns_rdata_freestruct(&dname);
5242 dns_name_format(qname, qbuf, sizeof(qbuf));
5243 dns_name_format(oname, obuf, sizeof(obuf));
5244 log_formerr(fctx, "unrelated DNAME in answer: "
5245 "%s is not in %s", qbuf, obuf);
5246 return (DNS_R_FORMERR);
5248 dns_fixedname_init(&prefix);
5249 dns_name_split(qname, nlabels, dns_fixedname_name(&prefix), NULL);
5250 dns_fixedname_init(fixeddname);
5251 result = dns_name_concatenate(dns_fixedname_name(&prefix),
5253 dns_fixedname_name(fixeddname), NULL);
5254 dns_rdata_freestruct(&dname);
5258 static isc_boolean_t
5259 is_answeraddress_allowed(dns_view_t *view, dns_name_t *name,
5260 dns_rdataset_t *rdataset)
5262 isc_result_t result;
5263 dns_rdata_t rdata = DNS_RDATA_INIT;
5265 struct in6_addr in6a;
5266 isc_netaddr_t netaddr;
5267 char addrbuf[ISC_NETADDR_FORMATSIZE];
5268 char namebuf[DNS_NAME_FORMATSIZE];
5273 /* By default, we allow any addresses. */
5274 if (view->denyansweracl == NULL)
5278 * If the owner name matches one in the exclusion list, either exactly
5279 * or partially, allow it.
5281 if (view->answeracl_exclude != NULL) {
5282 dns_rbtnode_t *node = NULL;
5284 result = dns_rbt_findnode(view->answeracl_exclude, name, NULL,
5285 &node, NULL, 0, NULL, NULL);
5287 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
5292 * Otherwise, search the filter list for a match for each address
5293 * record. If a match is found, the address should be filtered,
5294 * so should the entire answer.
5296 for (result = dns_rdataset_first(rdataset);
5297 result == ISC_R_SUCCESS;
5298 result = dns_rdataset_next(rdataset)) {
5299 dns_rdata_reset(&rdata);
5300 dns_rdataset_current(rdataset, &rdata);
5301 if (rdataset->type == dns_rdatatype_a) {
5302 INSIST(rdata.length == sizeof(ina.s_addr));
5303 memcpy(&ina.s_addr, rdata.data, sizeof(ina.s_addr));
5304 isc_netaddr_fromin(&netaddr, &ina);
5306 INSIST(rdata.length == sizeof(in6a.s6_addr));
5307 memcpy(in6a.s6_addr, rdata.data, sizeof(in6a.s6_addr));
5308 isc_netaddr_fromin6(&netaddr, &in6a);
5311 result = dns_acl_match(&netaddr, NULL, view->denyansweracl,
5312 &view->aclenv, &match, NULL);
5314 if (result == ISC_R_SUCCESS && match > 0) {
5315 isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
5316 dns_name_format(name, namebuf, sizeof(namebuf));
5317 dns_rdatatype_format(rdataset->type, typebuf,
5319 dns_rdataclass_format(rdataset->rdclass, classbuf,
5321 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
5322 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
5323 "answer address %s denied for %s/%s/%s",
5324 addrbuf, namebuf, typebuf, classbuf);
5332 static isc_boolean_t
5333 is_answertarget_allowed(dns_view_t *view, dns_name_t *name,
5334 dns_rdatatype_t type, dns_name_t *tname,
5337 isc_result_t result;
5338 dns_rbtnode_t *node = NULL;
5339 char qnamebuf[DNS_NAME_FORMATSIZE];
5340 char tnamebuf[DNS_NAME_FORMATSIZE];
5344 /* By default, we allow any target name. */
5345 if (view->denyanswernames == NULL)
5349 * If the owner name matches one in the exclusion list, either exactly
5350 * or partially, allow it.
5352 if (view->answernames_exclude != NULL) {
5353 result = dns_rbt_findnode(view->answernames_exclude, name, NULL,
5354 &node, NULL, 0, NULL, NULL);
5355 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
5360 * If the target name is a subdomain of the search domain, allow it.
5362 if (dns_name_issubdomain(tname, domain))
5366 * Otherwise, apply filters.
5368 result = dns_rbt_findnode(view->denyanswernames, tname, NULL, &node,
5369 NULL, 0, NULL, NULL);
5370 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
5371 dns_name_format(name, qnamebuf, sizeof(qnamebuf));
5372 dns_name_format(tname, tnamebuf, sizeof(tnamebuf));
5373 dns_rdatatype_format(type, typebuf, sizeof(typebuf));
5374 dns_rdataclass_format(view->rdclass, classbuf,
5376 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
5377 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
5378 "%s target %s denied for %s/%s",
5379 typebuf, tnamebuf, qnamebuf, classbuf);
5387 trim_ns_ttl(fetchctx_t *fctx, dns_name_t *name, dns_rdataset_t *rdataset) {
5388 char ns_namebuf[DNS_NAME_FORMATSIZE];
5389 char namebuf[DNS_NAME_FORMATSIZE];
5390 char tbuf[DNS_RDATATYPE_FORMATSIZE];
5392 if (fctx->ns_ttl_ok && rdataset->ttl > fctx->ns_ttl) {
5393 dns_name_format(name, ns_namebuf, sizeof(ns_namebuf));
5394 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
5395 dns_rdatatype_format(fctx->type, tbuf, sizeof(tbuf));
5397 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
5398 DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(10),
5399 "fctx %p: trimming ttl of %s/NS for %s/%s: "
5400 "%u -> %u", fctx, ns_namebuf, namebuf, tbuf,
5401 rdataset->ttl, fctx->ns_ttl);
5402 rdataset->ttl = fctx->ns_ttl;
5407 * Handle a no-answer response (NXDOMAIN, NXRRSET, or referral).
5408 * If look_in_options has LOOK_FOR_NS_IN_ANSWER then we look in the answer
5409 * section for the NS RRset if the query type is NS; if it has
5410 * LOOK_FOR_GLUE_IN_ANSWER we look for glue incorrectly returned in the answer
5411 * section for A and AAAA queries.
5413 #define LOOK_FOR_NS_IN_ANSWER 0x1
5414 #define LOOK_FOR_GLUE_IN_ANSWER 0x2
5417 noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
5418 unsigned int look_in_options)
5420 isc_result_t result;
5421 dns_message_t *message;
5422 dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name;
5423 dns_rdataset_t *rdataset, *ns_rdataset;
5424 isc_boolean_t aa, negative_response;
5425 dns_rdatatype_t type;
5426 dns_section_t section;
5428 FCTXTRACE("noanswer_response");
5430 if ((look_in_options & LOOK_FOR_NS_IN_ANSWER) != 0) {
5431 INSIST(fctx->type == dns_rdatatype_ns);
5432 section = DNS_SECTION_ANSWER;
5434 section = DNS_SECTION_AUTHORITY;
5436 message = fctx->rmessage;
5441 if (oqname == NULL) {
5443 * We have a normal, non-chained negative response or
5446 if ((message->flags & DNS_MESSAGEFLAG_AA) != 0)
5450 qname = &fctx->name;
5453 * We're being invoked by answer_response() after it has
5454 * followed a CNAME/DNAME chain.
5459 * If the current qname is not a subdomain of the query
5460 * domain, there's no point in looking at the authority
5461 * section without doing DNSSEC validation.
5463 * Until we do that validation, we'll just return success
5466 if (!dns_name_issubdomain(qname, &fctx->domain))
5467 return (ISC_R_SUCCESS);
5471 * We have to figure out if this is a negative response, or a
5476 * Sometimes we can tell if its a negative response by looking at
5477 * the message header.
5479 negative_response = ISC_FALSE;
5480 if (message->rcode == dns_rcode_nxdomain ||
5481 (message->counts[DNS_SECTION_ANSWER] == 0 &&
5482 message->counts[DNS_SECTION_AUTHORITY] == 0))
5483 negative_response = ISC_TRUE;
5486 * Process the authority section.
5492 result = dns_message_firstname(message, section);
5493 while (result == ISC_R_SUCCESS) {
5495 dns_message_currentname(message, section, &name);
5496 if (dns_name_issubdomain(name, &fctx->domain)) {
5498 * Look for NS/SOA RRsets first.
5500 for (rdataset = ISC_LIST_HEAD(name->list);
5502 rdataset = ISC_LIST_NEXT(rdataset, link)) {
5503 type = rdataset->type;
5504 if (type == dns_rdatatype_rrsig)
5505 type = rdataset->covers;
5506 if (((type == dns_rdatatype_ns ||
5507 type == dns_rdatatype_soa) &&
5508 !dns_name_issubdomain(qname, name))) {
5509 char qbuf[DNS_NAME_FORMATSIZE];
5510 char nbuf[DNS_NAME_FORMATSIZE];
5511 char tbuf[DNS_RDATATYPE_FORMATSIZE];
5512 dns_rdatatype_format(type, tbuf,
5514 dns_name_format(name, nbuf,
5516 dns_name_format(qname, qbuf,
5519 "unrelated %s %s in "
5520 "%s authority section",
5522 return (DNS_R_FORMERR);
5524 if (type == dns_rdatatype_ns) {
5528 * Only one set of NS RRs is allowed.
5530 if (rdataset->type ==
5532 if (ns_name != NULL &&
5539 return (DNS_R_FORMERR);
5542 ns_rdataset = rdataset;
5546 rdataset->attributes |=
5547 DNS_RDATASETATTR_CACHE;
5548 rdataset->trust = dns_trust_glue;
5550 if (type == dns_rdatatype_soa) {
5552 * SOA, or RRSIG SOA.
5554 * Only one SOA is allowed.
5556 if (rdataset->type ==
5557 dns_rdatatype_soa) {
5558 if (soa_name != NULL &&
5565 return (DNS_R_FORMERR);
5570 DNS_NAMEATTR_NCACHE;
5571 rdataset->attributes |=
5572 DNS_RDATASETATTR_NCACHE;
5575 dns_trust_authauthority;
5576 else if (ISFORWARDER(fctx->addrinfo))
5581 dns_trust_additional;
5585 result = dns_message_nextname(message, section);
5586 if (result == ISC_R_NOMORE)
5588 else if (result != ISC_R_SUCCESS)
5592 log_ns_ttl(fctx, "noanswer_response");
5594 if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) &&
5595 !dns_name_equal(ns_name, dns_rootname))
5596 trim_ns_ttl(fctx, ns_name, ns_rdataset);
5599 * A negative response has a SOA record (Type 2)
5600 * and a optional NS RRset (Type 1) or it has neither
5601 * a SOA or a NS RRset (Type 3, handled above) or
5602 * rcode is NXDOMAIN (handled above) in which case
5603 * the NS RRset is allowed (Type 4).
5605 if (soa_name != NULL)
5606 negative_response = ISC_TRUE;
5608 result = dns_message_firstname(message, section);
5609 while (result == ISC_R_SUCCESS) {
5611 dns_message_currentname(message, section, &name);
5612 if (dns_name_issubdomain(name, &fctx->domain)) {
5613 for (rdataset = ISC_LIST_HEAD(name->list);
5615 rdataset = ISC_LIST_NEXT(rdataset, link)) {
5616 type = rdataset->type;
5617 if (type == dns_rdatatype_rrsig)
5618 type = rdataset->covers;
5619 if (type == dns_rdatatype_nsec ||
5620 type == dns_rdatatype_nsec3) {
5622 * NSEC or RRSIG NSEC.
5624 if (negative_response) {
5626 DNS_NAMEATTR_NCACHE;
5627 rdataset->attributes |=
5628 DNS_RDATASETATTR_NCACHE;
5629 } else if (type == dns_rdatatype_nsec) {
5632 rdataset->attributes |=
5633 DNS_RDATASETATTR_CACHE;
5637 dns_trust_authauthority;
5638 else if (ISFORWARDER(fctx->addrinfo))
5643 dns_trust_additional;
5645 * No additional data needs to be
5648 } else if (type == dns_rdatatype_ds) {
5652 * These should only be here if
5653 * this is a referral, and there
5654 * should only be one DS RRset.
5656 if (ns_name == NULL) {
5660 return (DNS_R_FORMERR);
5662 if (rdataset->type ==
5664 if (ds_name != NULL &&
5671 return (DNS_R_FORMERR);
5677 rdataset->attributes |=
5678 DNS_RDATASETATTR_CACHE;
5681 dns_trust_authauthority;
5682 else if (ISFORWARDER(fctx->addrinfo))
5687 dns_trust_additional;
5691 result = dns_message_nextname(message, section);
5692 if (result == ISC_R_NOMORE)
5694 else if (result != ISC_R_SUCCESS)
5699 * Trigger lookups for DNS nameservers.
5701 if (negative_response && message->rcode == dns_rcode_noerror &&
5702 fctx->type == dns_rdatatype_ds && soa_name != NULL &&
5703 dns_name_equal(soa_name, qname) &&
5704 !dns_name_equal(qname, dns_rootname))
5705 return (DNS_R_CHASEDSSERVERS);
5708 * Did we find anything?
5710 if (!negative_response && ns_name == NULL) {
5714 if (oqname != NULL) {
5716 * We've already got a partial CNAME/DNAME chain,
5717 * and haven't found else anything useful here, but
5718 * no error has occurred since we have an answer.
5720 return (ISC_R_SUCCESS);
5723 * The responder is insane.
5725 log_formerr(fctx, "invalid response");
5726 return (DNS_R_FORMERR);
5731 * If we found both NS and SOA, they should be the same name.
5733 if (ns_name != NULL && soa_name != NULL && ns_name != soa_name) {
5734 log_formerr(fctx, "NS/SOA mismatch");
5735 return (DNS_R_FORMERR);
5739 * Do we have a referral? (We only want to follow a referral if
5740 * we're not following a chain.)
5742 if (!negative_response && ns_name != NULL && oqname == NULL) {
5744 * We already know ns_name is a subdomain of fctx->domain.
5745 * If ns_name is equal to fctx->domain, we're not making
5746 * progress. We return DNS_R_FORMERR so that we'll keep
5747 * trying other servers.
5749 if (dns_name_equal(ns_name, &fctx->domain)) {
5750 log_formerr(fctx, "non-improving referral");
5751 return (DNS_R_FORMERR);
5755 * If the referral name is not a parent of the query
5756 * name, consider the responder insane.
5758 if (! dns_name_issubdomain(&fctx->name, ns_name)) {
5760 log_formerr(fctx, "referral to non-parent");
5761 FCTXTRACE("referral to non-parent");
5762 return (DNS_R_FORMERR);
5766 * Mark any additional data related to this rdataset.
5767 * It's important that we do this before we change the
5770 INSIST(ns_rdataset != NULL);
5771 fctx->attributes |= FCTX_ATTR_GLUING;
5772 (void)dns_rdataset_additionaldata(ns_rdataset, check_related,
5774 #if CHECK_FOR_GLUE_IN_ANSWER
5776 * Look in the answer section for "glue" that is incorrectly
5777 * returned as a answer. This is needed if the server also
5778 * minimizes the response size by not adding records to the
5779 * additional section that are in the answer section or if
5780 * the record gets dropped due to message size constraints.
5782 if ((look_in_options & LOOK_FOR_GLUE_IN_ANSWER) != 0 &&
5783 (fctx->type == dns_rdatatype_aaaa ||
5784 fctx->type == dns_rdatatype_a))
5785 (void)dns_rdataset_additionaldata(ns_rdataset,
5786 check_answer, fctx);
5788 fctx->attributes &= ~FCTX_ATTR_GLUING;
5790 * NS rdatasets with 0 TTL cause problems.
5791 * dns_view_findzonecut() will not find them when we
5792 * try to follow the referral, and we'll SERVFAIL
5793 * because the best nameservers are now above QDOMAIN.
5794 * We force the TTL to 1 second to prevent this.
5796 if (ns_rdataset->ttl == 0)
5797 ns_rdataset->ttl = 1;
5799 * Set the current query domain to the referral name.
5801 * XXXRTH We should check if we're in forward-only mode, and
5802 * if so we should bail out.
5804 INSIST(dns_name_countlabels(&fctx->domain) > 0);
5805 dns_name_free(&fctx->domain, fctx->mctx);
5806 if (dns_rdataset_isassociated(&fctx->nameservers))
5807 dns_rdataset_disassociate(&fctx->nameservers);
5808 dns_name_init(&fctx->domain, NULL);
5809 result = dns_name_dup(ns_name, fctx->mctx, &fctx->domain);
5810 if (result != ISC_R_SUCCESS)
5812 fctx->attributes |= FCTX_ATTR_WANTCACHE;
5813 fctx->ns_ttl_ok = ISC_FALSE;
5814 log_ns_ttl(fctx, "DELEGATION");
5815 return (DNS_R_DELEGATION);
5819 * Since we're not doing a referral, we don't want to cache any
5820 * NS RRs we may have found.
5822 if (ns_name != NULL)
5823 ns_name->attributes &= ~DNS_NAMEATTR_CACHE;
5825 if (negative_response && oqname == NULL)
5826 fctx->attributes |= FCTX_ATTR_WANTNCACHE;
5828 return (ISC_R_SUCCESS);
5832 answer_response(fetchctx_t *fctx) {
5833 isc_result_t result;
5834 dns_message_t *message;
5835 dns_name_t *name, *qname, tname, *ns_name;
5836 dns_rdataset_t *rdataset, *ns_rdataset;
5837 isc_boolean_t done, external, chaining, aa, found, want_chaining;
5838 isc_boolean_t have_answer, found_cname, found_type, wanted_chaining;
5840 dns_rdatatype_t type;
5841 dns_fixedname_t dname, fqname;
5844 FCTXTRACE("answer_response");
5846 message = fctx->rmessage;
5849 * Examine the answer section, marking those rdatasets which are
5850 * part of the answer and should be cached.
5854 found_cname = ISC_FALSE;
5855 found_type = ISC_FALSE;
5856 chaining = ISC_FALSE;
5857 have_answer = ISC_FALSE;
5858 want_chaining = ISC_FALSE;
5859 POST(want_chaining);
5860 if ((message->flags & DNS_MESSAGEFLAG_AA) != 0)
5864 qname = &fctx->name;
5866 view = fctx->res->view;
5867 result = dns_message_firstname(message, DNS_SECTION_ANSWER);
5868 while (!done && result == ISC_R_SUCCESS) {
5870 dns_message_currentname(message, DNS_SECTION_ANSWER, &name);
5871 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
5872 if (dns_name_equal(name, qname)) {
5873 wanted_chaining = ISC_FALSE;
5874 for (rdataset = ISC_LIST_HEAD(name->list);
5876 rdataset = ISC_LIST_NEXT(rdataset, link)) {
5878 want_chaining = ISC_FALSE;
5880 if (rdataset->type == dns_rdatatype_nsec3) {
5882 * NSEC3 records are not allowed to
5883 * appear in the answer section.
5885 log_formerr(fctx, "NSEC3 in answer");
5886 return (DNS_R_FORMERR);
5890 * Apply filters, if given, on answers to reject
5891 * a malicious attempt of rebinding.
5893 if ((rdataset->type == dns_rdatatype_a ||
5894 rdataset->type == dns_rdatatype_aaaa) &&
5895 !is_answeraddress_allowed(view, name,
5897 return (DNS_R_SERVFAIL);
5900 if (rdataset->type == type && !found_cname) {
5902 * We've found an ordinary answer.
5905 found_type = ISC_TRUE;
5907 aflag = DNS_RDATASETATTR_ANSWER;
5908 } else if (type == dns_rdatatype_any) {
5910 * We've found an answer matching
5911 * an ANY query. There may be
5915 aflag = DNS_RDATASETATTR_ANSWER;
5916 } else if (rdataset->type == dns_rdatatype_rrsig
5917 && rdataset->covers == type
5920 * We've found a signature that
5921 * covers the type we're looking for.
5924 found_type = ISC_TRUE;
5925 aflag = DNS_RDATASETATTR_ANSWERSIG;
5926 } else if (rdataset->type ==
5930 * We're looking for something else,
5931 * but we found a CNAME.
5933 * Getting a CNAME response for some
5934 * query types is an error.
5936 if (type == dns_rdatatype_rrsig ||
5937 type == dns_rdatatype_dnskey ||
5938 type == dns_rdatatype_nsec ||
5939 type == dns_rdatatype_nsec3) {
5940 char buf[DNS_RDATATYPE_FORMATSIZE];
5941 dns_rdatatype_format(fctx->type,
5946 return (DNS_R_FORMERR);
5949 found_cname = ISC_TRUE;
5950 want_chaining = ISC_TRUE;
5951 aflag = DNS_RDATASETATTR_ANSWER;
5952 result = cname_target(rdataset,
5954 if (result != ISC_R_SUCCESS)
5956 /* Apply filters on the target name. */
5957 if (!is_answertarget_allowed(view,
5962 return (DNS_R_SERVFAIL);
5964 } else if (rdataset->type == dns_rdatatype_rrsig
5965 && rdataset->covers ==
5969 * We're looking for something else,
5970 * but we found a SIG CNAME.
5973 found_cname = ISC_TRUE;
5974 aflag = DNS_RDATASETATTR_ANSWERSIG;
5979 * We've found an answer to our
5984 rdataset->attributes |=
5985 DNS_RDATASETATTR_CACHE;
5986 rdataset->trust = dns_trust_answer;
5989 * This data is "the" answer
5990 * to our question only if
5991 * we're not chaining (i.e.
5992 * if we haven't followed
5993 * a CNAME or DNAME).
5997 DNS_RDATASETATTR_ANSWER)
5998 have_answer = ISC_TRUE;
6000 DNS_NAMEATTR_ANSWER;
6001 rdataset->attributes |= aflag;
6004 dns_trust_authanswer;
6005 } else if (external) {
6007 * This data is outside of
6008 * our query domain, and
6009 * may not be cached.
6011 rdataset->attributes |=
6012 DNS_RDATASETATTR_EXTERNAL;
6016 * Mark any additional data related
6019 (void)dns_rdataset_additionaldata(
6027 if (want_chaining) {
6028 wanted_chaining = ISC_TRUE;
6030 DNS_NAMEATTR_CHAINING;
6031 rdataset->attributes |=
6032 DNS_RDATASETATTR_CHAINING;
6037 * We could add an "else" clause here and
6038 * log that we're ignoring this rdataset.
6042 * If wanted_chaining is true, we've done
6043 * some chaining as the result of processing
6044 * this node, and thus we need to set
6047 * We don't set chaining inside of the
6048 * rdataset loop because doing that would
6049 * cause us to ignore the signatures of
6052 if (wanted_chaining)
6053 chaining = ISC_TRUE;
6056 * Look for a DNAME (or its SIG). Anything else is
6059 wanted_chaining = ISC_FALSE;
6060 for (rdataset = ISC_LIST_HEAD(name->list);
6062 rdataset = ISC_LIST_NEXT(rdataset, link)) {
6063 isc_boolean_t found_dname = ISC_FALSE;
6064 dns_name_t *dname_name;
6068 if (rdataset->type == dns_rdatatype_dname) {
6070 * We're looking for something else,
6071 * but we found a DNAME.
6073 * If we're not chaining, then the
6074 * DNAME should not be external.
6076 if (!chaining && external) {
6079 return (DNS_R_FORMERR);
6082 want_chaining = ISC_TRUE;
6083 POST(want_chaining);
6084 aflag = DNS_RDATASETATTR_ANSWER;
6085 result = dname_target(fctx, rdataset,
6088 if (result == ISC_R_NOSPACE) {
6090 * We can't construct the
6091 * DNAME target. Do not
6094 want_chaining = ISC_FALSE;
6095 POST(want_chaining);
6096 } else if (result != ISC_R_SUCCESS)
6099 found_dname = ISC_TRUE;
6101 dname_name = dns_fixedname_name(&dname);
6102 if (!is_answertarget_allowed(view,
6107 return (DNS_R_SERVFAIL);
6109 } else if (rdataset->type == dns_rdatatype_rrsig
6110 && rdataset->covers ==
6111 dns_rdatatype_dname) {
6113 * We've found a signature that
6117 aflag = DNS_RDATASETATTR_ANSWERSIG;
6122 * We've found an answer to our
6127 rdataset->attributes |=
6128 DNS_RDATASETATTR_CACHE;
6129 rdataset->trust = dns_trust_answer;
6132 * This data is "the" answer
6133 * to our question only if
6134 * we're not chaining.
6138 DNS_RDATASETATTR_ANSWER)
6139 have_answer = ISC_TRUE;
6141 DNS_NAMEATTR_ANSWER;
6142 rdataset->attributes |= aflag;
6145 dns_trust_authanswer;
6146 } else if (external) {
6147 rdataset->attributes |=
6148 DNS_RDATASETATTR_EXTERNAL;
6156 * Copy the dname into the
6159 * Although we check for
6160 * failure of the copy
6161 * operation, in practice it
6162 * should never fail since
6163 * we already know that the
6164 * result fits in a fixedname.
6166 dns_fixedname_init(&fqname);
6167 result = dns_name_copy(
6168 dns_fixedname_name(&dname),
6169 dns_fixedname_name(&fqname),
6171 if (result != ISC_R_SUCCESS)
6173 wanted_chaining = ISC_TRUE;
6175 DNS_NAMEATTR_CHAINING;
6176 rdataset->attributes |=
6177 DNS_RDATASETATTR_CHAINING;
6178 qname = dns_fixedname_name(
6183 if (wanted_chaining)
6184 chaining = ISC_TRUE;
6186 result = dns_message_nextname(message, DNS_SECTION_ANSWER);
6188 if (result == ISC_R_NOMORE)
6189 result = ISC_R_SUCCESS;
6190 if (result != ISC_R_SUCCESS)
6194 * We should have found an answer.
6197 log_formerr(fctx, "reply has no answer");
6198 return (DNS_R_FORMERR);
6202 * This response is now potentially cacheable.
6204 fctx->attributes |= FCTX_ATTR_WANTCACHE;
6207 * Did chaining end before we got the final answer?
6211 * Yes. This may be a negative reply, so hand off
6212 * authority section processing to the noanswer code.
6213 * If it isn't a noanswer response, no harm will be
6216 return (noanswer_response(fctx, qname, 0));
6220 * We didn't end with an incomplete chain, so the rcode should be
6223 if (message->rcode != dns_rcode_noerror) {
6224 log_formerr(fctx, "CNAME/DNAME chain complete, but RCODE "
6226 return (DNS_R_FORMERR);
6230 * Examine the authority section (if there is one).
6232 * We expect there to be only one owner name for all the rdatasets
6233 * in this section, and we expect that it is not external.
6238 result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
6239 while (!done && result == ISC_R_SUCCESS) {
6241 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
6242 external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
6245 * We expect to find NS or SIG NS rdatasets, and
6248 for (rdataset = ISC_LIST_HEAD(name->list);
6250 rdataset = ISC_LIST_NEXT(rdataset, link)) {
6251 if (rdataset->type == dns_rdatatype_ns ||
6252 (rdataset->type == dns_rdatatype_rrsig &&
6253 rdataset->covers == dns_rdatatype_ns)) {
6256 rdataset->attributes |=
6257 DNS_RDATASETATTR_CACHE;
6258 if (aa && !chaining)
6260 dns_trust_authauthority;
6263 dns_trust_additional;
6265 if (rdataset->type == dns_rdatatype_ns) {
6267 ns_rdataset = rdataset;
6270 * Mark any additional data related
6273 (void)dns_rdataset_additionaldata(
6281 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY);
6283 if (result == ISC_R_NOMORE)
6284 result = ISC_R_SUCCESS;
6286 log_ns_ttl(fctx, "answer_response");
6288 if (ns_rdataset != NULL && dns_name_equal(&fctx->domain, ns_name) &&
6289 !dns_name_equal(ns_name, dns_rootname))
6290 trim_ns_ttl(fctx, ns_name, ns_rdataset);
6295 static isc_boolean_t
6296 fctx_decreference(fetchctx_t *fctx) {
6297 isc_boolean_t bucket_empty = ISC_FALSE;
6299 INSIST(fctx->references > 0);
6301 if (fctx->references == 0) {
6303 * No one cares about the result of this fetch anymore.
6305 if (fctx->pending == 0 && fctx->nqueries == 0 &&
6306 ISC_LIST_EMPTY(fctx->validators) && SHUTTINGDOWN(fctx)) {
6308 * This fctx is already shutdown; we were just
6309 * waiting for the last reference to go away.
6311 bucket_empty = fctx_unlink(fctx);
6315 * Initiate shutdown.
6317 fctx_shutdown(fctx);
6320 return (bucket_empty);
6324 resume_dslookup(isc_task_t *task, isc_event_t *event) {
6325 dns_fetchevent_t *fevent;
6326 dns_resolver_t *res;
6328 isc_result_t result;
6329 isc_boolean_t bucket_empty;
6330 isc_boolean_t locked = ISC_FALSE;
6331 unsigned int bucketnum;
6332 dns_rdataset_t nameservers;
6333 dns_fixedname_t fixed;
6336 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
6337 fevent = (dns_fetchevent_t *)event;
6338 fctx = event->ev_arg;
6339 REQUIRE(VALID_FCTX(fctx));
6343 FCTXTRACE("resume_dslookup");
6345 if (fevent->node != NULL)
6346 dns_db_detachnode(fevent->db, &fevent->node);
6347 if (fevent->db != NULL)
6348 dns_db_detach(&fevent->db);
6350 dns_rdataset_init(&nameservers);
6352 bucketnum = fctx->bucketnum;
6353 if (fevent->result == ISC_R_CANCELED) {
6354 dns_resolver_destroyfetch(&fctx->nsfetch);
6355 fctx_done(fctx, ISC_R_CANCELED, __LINE__);
6356 } else if (fevent->result == ISC_R_SUCCESS) {
6358 FCTXTRACE("resuming DS lookup");
6360 dns_resolver_destroyfetch(&fctx->nsfetch);
6361 if (dns_rdataset_isassociated(&fctx->nameservers))
6362 dns_rdataset_disassociate(&fctx->nameservers);
6363 dns_rdataset_clone(fevent->rdataset, &fctx->nameservers);
6364 fctx->ns_ttl = fctx->nameservers.ttl;
6365 fctx->ns_ttl_ok = ISC_TRUE;
6366 log_ns_ttl(fctx, "resume_dslookup");
6367 dns_name_free(&fctx->domain, fctx->mctx);
6368 dns_name_init(&fctx->domain, NULL);
6369 result = dns_name_dup(&fctx->nsname, fctx->mctx, &fctx->domain);
6370 if (result != ISC_R_SUCCESS) {
6371 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
6377 fctx_try(fctx, ISC_TRUE, ISC_FALSE);
6380 dns_rdataset_t *nsrdataset = NULL;
6383 * Retrieve state from fctx->nsfetch before we destroy it.
6385 dns_fixedname_init(&fixed);
6386 domain = dns_fixedname_name(&fixed);
6387 dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL);
6388 if (dns_name_equal(&fctx->nsname, domain)) {
6389 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
6390 dns_resolver_destroyfetch(&fctx->nsfetch);
6393 if (dns_rdataset_isassociated(
6394 &fctx->nsfetch->private->nameservers)) {
6396 &fctx->nsfetch->private->nameservers,
6398 nsrdataset = &nameservers;
6401 dns_resolver_destroyfetch(&fctx->nsfetch);
6402 n = dns_name_countlabels(&fctx->nsname);
6403 dns_name_getlabelsequence(&fctx->nsname, 1, n - 1,
6406 if (dns_rdataset_isassociated(fevent->rdataset))
6407 dns_rdataset_disassociate(fevent->rdataset);
6408 FCTXTRACE("continuing to look for parent's NS records");
6409 result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
6410 dns_rdatatype_ns, domain,
6411 nsrdataset, NULL, 0, task,
6412 resume_dslookup, fctx,
6413 &fctx->nsrrset, NULL,
6415 if (result != ISC_R_SUCCESS)
6416 fctx_done(fctx, result, __LINE__);
6418 LOCK(&res->buckets[bucketnum].lock);
6425 if (dns_rdataset_isassociated(&nameservers))
6426 dns_rdataset_disassociate(&nameservers);
6427 if (dns_rdataset_isassociated(fevent->rdataset))
6428 dns_rdataset_disassociate(fevent->rdataset);
6429 INSIST(fevent->sigrdataset == NULL);
6430 isc_event_free(&event);
6432 LOCK(&res->buckets[bucketnum].lock);
6433 bucket_empty = fctx_decreference(fctx);
6434 UNLOCK(&res->buckets[bucketnum].lock);
6440 checknamessection(dns_message_t *message, dns_section_t section) {
6441 isc_result_t result;
6443 dns_rdata_t rdata = DNS_RDATA_INIT;
6444 dns_rdataset_t *rdataset;
6446 for (result = dns_message_firstname(message, section);
6447 result == ISC_R_SUCCESS;
6448 result = dns_message_nextname(message, section))
6451 dns_message_currentname(message, section, &name);
6452 for (rdataset = ISC_LIST_HEAD(name->list);
6454 rdataset = ISC_LIST_NEXT(rdataset, link)) {
6455 for (result = dns_rdataset_first(rdataset);
6456 result == ISC_R_SUCCESS;
6457 result = dns_rdataset_next(rdataset)) {
6458 dns_rdataset_current(rdataset, &rdata);
6459 if (!dns_rdata_checkowner(name, rdata.rdclass,
6462 !dns_rdata_checknames(&rdata, name, NULL))
6464 rdataset->attributes |=
6465 DNS_RDATASETATTR_CHECKNAMES;
6467 dns_rdata_reset(&rdata);
6474 checknames(dns_message_t *message) {
6476 checknamessection(message, DNS_SECTION_ANSWER);
6477 checknamessection(message, DNS_SECTION_AUTHORITY);
6478 checknamessection(message, DNS_SECTION_ADDITIONAL);
6482 * Log server NSID at log level 'level'
6485 log_nsid(dns_rdataset_t *opt, resquery_t *query, int level, isc_mem_t *mctx)
6487 static const char hex[17] = "0123456789abcdef";
6488 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6489 isc_uint16_t optcode, nsid_len, buflen, i;
6490 isc_result_t result;
6491 isc_buffer_t nsidbuf;
6493 unsigned char *p, *buf, *nsid;
6495 /* Extract rdata from OPT rdataset */
6496 result = dns_rdataset_first(opt);
6497 if (result != ISC_R_SUCCESS)
6498 return (ISC_R_FAILURE);
6500 dns_rdata_init(&rdata);
6501 dns_rdataset_current(opt, &rdata);
6502 if (rdata.length < 4)
6503 return (ISC_R_FAILURE);
6505 /* Check for NSID */
6506 isc_buffer_init(&nsidbuf, rdata.data, rdata.length);
6507 isc_buffer_add(&nsidbuf, rdata.length);
6508 optcode = isc_buffer_getuint16(&nsidbuf);
6509 nsid_len = isc_buffer_getuint16(&nsidbuf);
6510 if (optcode != DNS_OPT_NSID || nsid_len == 0)
6511 return (ISC_R_FAILURE);
6513 /* Allocate buffer for storing hex version of the NSID */
6514 buflen = nsid_len * 2 + 1;
6515 buf = isc_mem_get(mctx, buflen);
6517 return (ISC_R_NOSPACE);
6519 /* Convert to hex */
6521 nsid = rdata.data + 4;
6522 for (i = 0; i < nsid_len; i++) {
6523 *p++ = hex[(nsid[0] >> 4) & 0xf];
6524 *p++ = hex[nsid[0] & 0xf];
6529 isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
6531 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
6532 DNS_LOGMODULE_RESOLVER, level,
6533 "received NSID '%s' from %s", buf, addrbuf);
6536 isc_mem_put(mctx, buf, buflen);
6537 return (ISC_R_SUCCESS);
6541 log_packet(dns_message_t *message, int level, isc_mem_t *mctx) {
6542 isc_buffer_t buffer;
6545 isc_result_t result;
6547 if (! isc_log_wouldlog(dns_lctx, level))
6551 * Note that these are multiline debug messages. We want a newline
6552 * to appear in the log after each message.
6556 buf = isc_mem_get(mctx, len);
6559 isc_buffer_init(&buffer, buf, len);
6560 result = dns_message_totext(message, &dns_master_style_debug,
6562 if (result == ISC_R_NOSPACE) {
6563 isc_mem_put(mctx, buf, len);
6565 } else if (result == ISC_R_SUCCESS)
6566 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
6567 DNS_LOGMODULE_RESOLVER, level,
6568 "received packet:\n%.*s",
6569 (int)isc_buffer_usedlength(&buffer),
6571 } while (result == ISC_R_NOSPACE);
6574 isc_mem_put(mctx, buf, len);
6577 static isc_boolean_t
6578 iscname(fetchctx_t *fctx) {
6579 isc_result_t result;
6581 result = dns_message_findname(fctx->rmessage, DNS_SECTION_ANSWER,
6582 &fctx->name, dns_rdatatype_cname, 0,
6584 return (result == ISC_R_SUCCESS ? ISC_TRUE : ISC_FALSE);
6587 static isc_boolean_t
6588 betterreferral(fetchctx_t *fctx) {
6589 isc_result_t result;
6591 dns_rdataset_t *rdataset;
6592 dns_message_t *message = fctx->rmessage;
6594 for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
6595 result == ISC_R_SUCCESS;
6596 result = dns_message_nextname(message, DNS_SECTION_AUTHORITY)) {
6598 dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
6599 if (!isstrictsubdomain(name, &fctx->domain))
6601 for (rdataset = ISC_LIST_HEAD(name->list);
6603 rdataset = ISC_LIST_NEXT(rdataset, link))
6604 if (rdataset->type == dns_rdatatype_ns)
6611 resquery_response(isc_task_t *task, isc_event_t *event) {
6612 isc_result_t result = ISC_R_SUCCESS;
6613 resquery_t *query = event->ev_arg;
6614 dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
6615 isc_boolean_t keep_trying, get_nameservers, resend;
6616 isc_boolean_t truncated;
6617 dns_message_t *message;
6618 dns_rdataset_t *opt;
6621 dns_fixedname_t foundname;
6623 isc_time_t tnow, *finish;
6624 dns_adbaddrinfo_t *addrinfo;
6625 unsigned int options;
6626 unsigned int findoptions;
6627 isc_result_t broken_server;
6628 badnstype_t broken_type = badns_response;
6629 isc_boolean_t no_response;
6631 REQUIRE(VALID_QUERY(query));
6633 options = query->options;
6634 REQUIRE(VALID_FCTX(fctx));
6635 REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
6639 if (isc_sockaddr_pf(&query->addrinfo->sockaddr) == PF_INET)
6640 inc_stats(fctx->res, dns_resstatscounter_responsev4);
6642 inc_stats(fctx->res, dns_resstatscounter_responsev6);
6644 (void)isc_timer_touch(fctx->timer);
6646 keep_trying = ISC_FALSE;
6647 broken_server = ISC_R_SUCCESS;
6648 get_nameservers = ISC_FALSE;
6650 truncated = ISC_FALSE;
6652 no_response = ISC_FALSE;
6654 if (fctx->res->exiting) {
6655 result = ISC_R_SHUTTINGDOWN;
6660 fctx->timeout = ISC_FALSE;
6661 fctx->addrinfo = query->addrinfo;
6664 * XXXRTH We should really get the current time just once. We
6665 * need a routine to convert from an isc_time_t to an
6670 isc_stdtime_get(&now);
6673 * Did the dispatcher have a problem?
6675 if (devent->result != ISC_R_SUCCESS) {
6676 if (devent->result == ISC_R_EOF &&
6677 (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
6679 * The problem might be that they
6680 * don't understand EDNS0. Turn it
6681 * off and try again.
6683 options |= DNS_FETCHOPT_NOEDNS0;
6686 * Remember that they don't like EDNS0.
6688 dns_adb_changeflags(fctx->adb,
6690 DNS_FETCHOPT_NOEDNS0,
6691 DNS_FETCHOPT_NOEDNS0);
6694 * There's no hope for this query.
6696 keep_trying = ISC_TRUE;
6699 * If this is a network error on an exclusive query
6700 * socket, mark the server as bad so that we won't try
6701 * it for this fetch again. Also adjust finish and
6702 * no_response so that we penalize this address in SRTT
6705 if (query->exclusivesocket &&
6706 (devent->result == ISC_R_HOSTUNREACH ||
6707 devent->result == ISC_R_NETUNREACH ||
6708 devent->result == ISC_R_CONNREFUSED ||
6709 devent->result == ISC_R_CANCELED)) {
6710 broken_server = devent->result;
6711 broken_type = badns_unreachable;
6713 no_response = ISC_TRUE;
6719 message = fctx->rmessage;
6721 if (query->tsig != NULL) {
6722 result = dns_message_setquerytsig(message, query->tsig);
6723 if (result != ISC_R_SUCCESS)
6727 if (query->tsigkey) {
6728 result = dns_message_settsigkey(message, query->tsigkey);
6729 if (result != ISC_R_SUCCESS)
6733 result = dns_message_parse(message, &devent->buffer, 0);
6734 if (result != ISC_R_SUCCESS) {
6736 case ISC_R_UNEXPECTEDEND:
6737 if (!message->question_ok ||
6738 (message->flags & DNS_MESSAGEFLAG_TC) == 0 ||
6739 (options & DNS_FETCHOPT_TCP) != 0) {
6741 * Either the message ended prematurely,
6742 * and/or wasn't marked as being truncated,
6743 * and/or this is a response to a query we
6744 * sent over TCP. In all of these cases,
6745 * something is wrong with the remote
6746 * server and we don't want to retry using
6749 if ((query->options & DNS_FETCHOPT_NOEDNS0)
6752 * The problem might be that they
6753 * don't understand EDNS0. Turn it
6754 * off and try again.
6756 options |= DNS_FETCHOPT_NOEDNS0;
6759 * Remember that they don't like EDNS0.
6761 dns_adb_changeflags(
6764 DNS_FETCHOPT_NOEDNS0,
6765 DNS_FETCHOPT_NOEDNS0);
6766 inc_stats(fctx->res,
6767 dns_resstatscounter_edns0fail);
6769 broken_server = result;
6770 keep_trying = ISC_TRUE;
6775 * We defer retrying via TCP for a bit so we can
6776 * check out this message further.
6778 truncated = ISC_TRUE;
6781 if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
6783 * The problem might be that they
6784 * don't understand EDNS0. Turn it
6785 * off and try again.
6787 options |= DNS_FETCHOPT_NOEDNS0;
6790 * Remember that they don't like EDNS0.
6792 dns_adb_changeflags(fctx->adb,
6794 DNS_FETCHOPT_NOEDNS0,
6795 DNS_FETCHOPT_NOEDNS0);
6796 inc_stats(fctx->res,
6797 dns_resstatscounter_edns0fail);
6799 broken_server = DNS_R_UNEXPECTEDRCODE;
6800 keep_trying = ISC_TRUE;
6805 * Something bad has happened.
6813 * Log the incoming packet.
6815 log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx);
6818 * Did we request NSID? If so, and if the response contains
6819 * NSID data, log it at INFO level.
6821 opt = dns_message_getopt(message);
6822 if (opt != NULL && (query->options & DNS_FETCHOPT_WANTNSID) != 0)
6823 log_nsid(opt, query, ISC_LOG_INFO, fctx->res->mctx);
6826 * If the message is signed, check the signature. If not, this
6827 * returns success anyway.
6829 result = dns_message_checksig(message, fctx->res->view);
6830 if (result != ISC_R_SUCCESS)
6834 * The dispatcher should ensure we only get responses with QR set.
6836 INSIST((message->flags & DNS_MESSAGEFLAG_QR) != 0);
6838 * INSIST() that the message comes from the place we sent it to,
6839 * since the dispatch code should ensure this.
6841 * INSIST() that the message id is correct (this should also be
6842 * ensured by the dispatch code).
6846 * We have an affirmative response to the query and we have
6847 * previously got a response from this server which indicated
6848 * EDNS may not be supported so we can now cache the lack of
6852 (message->rcode == dns_rcode_noerror ||
6853 message->rcode == dns_rcode_nxdomain ||
6854 message->rcode == dns_rcode_refused ||
6855 message->rcode == dns_rcode_yxdomain) &&
6856 bad_edns(fctx, &query->addrinfo->sockaddr)) {
6857 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
6858 isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
6860 dns_adb_changeflags(fctx->adb, query->addrinfo,
6861 DNS_FETCHOPT_NOEDNS0,
6862 DNS_FETCHOPT_NOEDNS0);
6866 * Deal with truncated responses by retrying using TCP.
6868 if ((message->flags & DNS_MESSAGEFLAG_TC) != 0)
6869 truncated = ISC_TRUE;
6872 inc_stats(fctx->res, dns_resstatscounter_truncated);
6873 if ((options & DNS_FETCHOPT_TCP) != 0) {
6874 broken_server = DNS_R_TRUNCATEDTCP;
6875 keep_trying = ISC_TRUE;
6877 options |= DNS_FETCHOPT_TCP;
6884 * Is it a query response?
6886 if (message->opcode != dns_opcode_query) {
6888 broken_server = DNS_R_UNEXPECTEDOPCODE;
6889 keep_trying = ISC_TRUE;
6894 * Update statistics about erroneous responses.
6896 if (message->rcode != dns_rcode_noerror) {
6897 switch (message->rcode) {
6898 case dns_rcode_nxdomain:
6899 inc_stats(fctx->res, dns_resstatscounter_nxdomain);
6901 case dns_rcode_servfail:
6902 inc_stats(fctx->res, dns_resstatscounter_servfail);
6904 case dns_rcode_formerr:
6905 inc_stats(fctx->res, dns_resstatscounter_formerr);
6908 inc_stats(fctx->res, dns_resstatscounter_othererror);
6914 * Is the remote server broken, or does it dislike us?
6916 if (message->rcode != dns_rcode_noerror &&
6917 message->rcode != dns_rcode_nxdomain) {
6918 if (((message->rcode == dns_rcode_formerr ||
6919 message->rcode == dns_rcode_notimp) ||
6920 (message->rcode == dns_rcode_servfail &&
6921 dns_message_getopt(message) == NULL)) &&
6922 (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
6924 * It's very likely they don't like EDNS0.
6925 * If the response code is SERVFAIL, also check if the
6926 * response contains an OPT RR and don't cache the
6927 * failure since it can be returned for various other
6930 * XXXRTH We should check if the question
6931 * we're asking requires EDNS0, and
6932 * if so, we should bail out.
6934 options |= DNS_FETCHOPT_NOEDNS0;
6937 * Remember that they may not like EDNS0.
6939 add_bad_edns(fctx, &query->addrinfo->sockaddr);
6940 inc_stats(fctx->res, dns_resstatscounter_edns0fail);
6941 } else if (message->rcode == dns_rcode_formerr) {
6942 if (ISFORWARDER(query->addrinfo)) {
6944 * This forwarder doesn't understand us,
6945 * but other forwarders might. Keep trying.
6947 broken_server = DNS_R_REMOTEFORMERR;
6948 keep_trying = ISC_TRUE;
6951 * The server doesn't understand us. Since
6952 * all servers for a zone need similar
6953 * capabilities, we assume that we will get
6954 * FORMERR from all servers, and thus we
6955 * cannot make any more progress with this
6958 log_formerr(fctx, "server sent FORMERR");
6959 result = DNS_R_FORMERR;
6961 } else if (message->rcode == dns_rcode_yxdomain) {
6963 * DNAME mapping failed because the new name
6964 * was too long. There's no chance of success
6967 result = DNS_R_YXDOMAIN;
6968 } else if (message->rcode == dns_rcode_badvers) {
6969 unsigned int flags, mask;
6970 unsigned int version;
6973 INSIST(opt != NULL);
6974 version = (opt->ttl >> 16) & 0xff;
6975 flags = (version << DNS_FETCHOPT_EDNSVERSIONSHIFT) |
6976 DNS_FETCHOPT_EDNSVERSIONSET;
6977 mask = DNS_FETCHOPT_EDNSVERSIONMASK |
6978 DNS_FETCHOPT_EDNSVERSIONSET;
6981 dns_adb_changeflags(fctx->adb, query->addrinfo,
6985 broken_server = DNS_R_BADVERS;
6986 keep_trying = ISC_TRUE;
6993 broken_server = DNS_R_UNEXPECTEDRCODE;
6994 INSIST(broken_server != ISC_R_SUCCESS);
6995 keep_trying = ISC_TRUE;
7001 * Is the question the same as the one we asked?
7003 result = same_question(fctx);
7004 if (result != ISC_R_SUCCESS) {
7006 if (result == DNS_R_FORMERR)
7007 keep_trying = ISC_TRUE;
7012 * Is the server lame?
7014 if (fctx->res->lame_ttl != 0 && !ISFORWARDER(query->addrinfo) &&
7016 inc_stats(fctx->res, dns_resstatscounter_lame);
7017 log_lame(fctx, query->addrinfo);
7018 result = dns_adb_marklame(fctx->adb, query->addrinfo,
7019 &fctx->name, fctx->type,
7020 now + fctx->res->lame_ttl);
7021 if (result != ISC_R_SUCCESS)
7022 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
7023 DNS_LOGMODULE_RESOLVER, ISC_LOG_ERROR,
7024 "could not mark server as lame: %s",
7025 isc_result_totext(result));
7026 broken_server = DNS_R_LAME;
7027 keep_trying = ISC_TRUE;
7032 * Enforce delegations only zones like NET and COM.
7034 if (!ISFORWARDER(query->addrinfo) &&
7035 dns_view_isdelegationonly(fctx->res->view, &fctx->domain) &&
7036 !dns_name_equal(&fctx->domain, &fctx->name) &&
7037 fix_mustbedelegationornxdomain(message, fctx)) {
7038 char namebuf[DNS_NAME_FORMATSIZE];
7039 char domainbuf[DNS_NAME_FORMATSIZE];
7040 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
7044 dns_name_format(&fctx->name, namebuf, sizeof(namebuf));
7045 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
7046 dns_rdatatype_format(fctx->type, typebuf, sizeof(typebuf));
7047 dns_rdataclass_format(fctx->res->rdclass, classbuf,
7049 isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
7052 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DELEGATION_ONLY,
7053 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
7054 "enforced delegation-only for '%s' (%s/%s/%s) "
7056 domainbuf, namebuf, typebuf, classbuf, addrbuf);
7059 if ((fctx->res->options & DNS_RESOLVER_CHECKNAMES) != 0)
7060 checknames(message);
7065 fctx->attributes &= ~(FCTX_ATTR_WANTNCACHE | FCTX_ATTR_WANTCACHE);
7068 * Did we get any answers?
7070 if (message->counts[DNS_SECTION_ANSWER] > 0 &&
7071 (message->rcode == dns_rcode_noerror ||
7072 message->rcode == dns_rcode_nxdomain)) {
7075 * We've got answers. If it has an authoritative answer or an
7076 * answer from a forwarder, we're done.
7078 if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 ||
7079 ISFORWARDER(query->addrinfo))
7080 result = answer_response(fctx);
7081 else if (iscname(fctx) &&
7082 fctx->type != dns_rdatatype_any &&
7083 fctx->type != dns_rdatatype_cname) {
7085 * A BIND8 server could return a non-authoritative
7086 * answer when a CNAME is followed. We should treat
7087 * it as a valid answer.
7089 result = answer_response(fctx);
7090 } else if (fctx->type != dns_rdatatype_ns &&
7091 !betterreferral(fctx)) {
7093 * Lame response !!!.
7095 result = answer_response(fctx);
7097 if (fctx->type == dns_rdatatype_ns) {
7099 * A BIND 8 server could incorrectly return a
7100 * non-authoritative answer to an NS query
7101 * instead of a referral. Since this answer
7102 * lacks the SIGs necessary to do DNSSEC
7103 * validation, we must invoke the following
7104 * special kludge to treat it as a referral.
7106 result = noanswer_response(fctx, NULL,
7107 LOOK_FOR_NS_IN_ANSWER);
7110 * Some other servers may still somehow include
7111 * an answer when it should return a referral
7112 * with an empty answer. Check to see if we can
7113 * treat this as a referral by ignoring the
7114 * answer. Further more, there may be an
7115 * implementation that moves A/AAAA glue records
7116 * to the answer section for that type of
7117 * delegation when the query is for that glue
7118 * record. LOOK_FOR_GLUE_IN_ANSWER will handle
7119 * such a corner case.
7121 result = noanswer_response(fctx, NULL,
7122 LOOK_FOR_GLUE_IN_ANSWER);
7124 if (result != DNS_R_DELEGATION) {
7126 * At this point, AA is not set, the response
7127 * is not a referral, and the server is not a
7128 * forwarder. It is technically lame and it's
7129 * easier to treat it as such than to figure out
7130 * some more elaborate course of action.
7132 broken_server = DNS_R_LAME;
7133 keep_trying = ISC_TRUE;
7136 goto force_referral;
7138 if (result != ISC_R_SUCCESS) {
7139 if (result == DNS_R_FORMERR)
7140 keep_trying = ISC_TRUE;
7143 } else if (message->counts[DNS_SECTION_AUTHORITY] > 0 ||
7144 message->rcode == dns_rcode_noerror ||
7145 message->rcode == dns_rcode_nxdomain) {
7147 * NXDOMAIN, NXRDATASET, or referral.
7149 result = noanswer_response(fctx, NULL, 0);
7150 if (result == DNS_R_CHASEDSSERVERS) {
7151 } else if (result == DNS_R_DELEGATION) {
7154 * We don't have the answer, but we know a better
7157 get_nameservers = ISC_TRUE;
7158 keep_trying = ISC_TRUE;
7160 * We have a new set of name servers, and it
7161 * has not experienced any restarts yet.
7166 * Update local statistics counters collected for each
7170 fctx->querysent = 0;
7171 fctx->lamecount = 0;
7176 result = ISC_R_SUCCESS;
7177 } else if (result != ISC_R_SUCCESS) {
7179 * Something has gone wrong.
7181 if (result == DNS_R_FORMERR)
7182 keep_trying = ISC_TRUE;
7187 * The server is insane.
7190 broken_server = DNS_R_UNEXPECTEDRCODE;
7191 keep_trying = ISC_TRUE;
7196 * Follow additional section data chains.
7198 chase_additional(fctx);
7201 * Cache the cacheable parts of the message. This may also cause
7202 * work to be queued to the DNSSEC validator.
7204 if (WANTCACHE(fctx)) {
7205 result = cache_message(fctx, query->addrinfo, now);
7206 if (result != ISC_R_SUCCESS)
7211 * Ncache the negatively cacheable parts of the message. This may
7212 * also cause work to be queued to the DNSSEC validator.
7214 if (WANTNCACHE(fctx)) {
7215 dns_rdatatype_t covers;
7216 if (message->rcode == dns_rcode_nxdomain)
7217 covers = dns_rdatatype_any;
7219 covers = fctx->type;
7222 * Cache any negative cache entries in the message.
7224 result = ncache_message(fctx, query->addrinfo, covers, now);
7229 * Remember the query's addrinfo, in case we need to mark the
7232 addrinfo = query->addrinfo;
7237 * XXXRTH Don't cancel the query if waiting for validation?
7239 fctx_cancelquery(&query, &devent, finish, no_response);
7242 if (result == DNS_R_FORMERR)
7243 broken_server = DNS_R_FORMERR;
7244 if (broken_server != ISC_R_SUCCESS) {
7246 * Add this server to the list of bad servers for
7249 add_bad(fctx, addrinfo, broken_server, broken_type);
7252 if (get_nameservers) {
7254 dns_fixedname_init(&foundname);
7255 fname = dns_fixedname_name(&foundname);
7256 if (result != ISC_R_SUCCESS) {
7257 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
7261 if (dns_rdatatype_atparent(fctx->type))
7262 findoptions |= DNS_DBFIND_NOEXACT;
7263 if ((options & DNS_FETCHOPT_UNSHARED) == 0)
7266 name = &fctx->domain;
7267 result = dns_view_findzonecut(fctx->res->view,
7273 if (result != ISC_R_SUCCESS) {
7274 FCTXTRACE("couldn't find a zonecut");
7275 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
7278 if (!dns_name_issubdomain(fname, &fctx->domain)) {
7280 * The best nameservers are now above our
7283 FCTXTRACE("nameservers now above QDOMAIN");
7284 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
7287 dns_name_free(&fctx->domain, fctx->mctx);
7288 dns_name_init(&fctx->domain, NULL);
7289 result = dns_name_dup(fname, fctx->mctx, &fctx->domain);
7290 if (result != ISC_R_SUCCESS) {
7291 fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
7294 fctx->ns_ttl = fctx->nameservers.ttl;
7295 fctx->ns_ttl_ok = ISC_TRUE;
7296 fctx_cancelqueries(fctx, ISC_TRUE);
7297 fctx_cleanupfinds(fctx);
7298 fctx_cleanupaltfinds(fctx);
7299 fctx_cleanupforwaddrs(fctx);
7300 fctx_cleanupaltaddrs(fctx);
7305 fctx_try(fctx, !get_nameservers, ISC_FALSE);
7306 } else if (resend) {
7308 * Resend (probably with changed options).
7310 FCTXTRACE("resend");
7311 inc_stats(fctx->res, dns_resstatscounter_retry);
7312 result = fctx_query(fctx, addrinfo, options);
7313 if (result != ISC_R_SUCCESS)
7314 fctx_done(fctx, result, __LINE__);
7315 } else if (result == ISC_R_SUCCESS && !HAVE_ANSWER(fctx)) {
7317 * All has gone well so far, but we are waiting for the
7318 * DNSSEC validator to validate the answer.
7320 FCTXTRACE("wait for validator");
7321 fctx_cancelqueries(fctx, ISC_TRUE);
7323 * We must not retransmit while the validator is working;
7324 * it has references to the current rmessage.
7326 result = fctx_stopidletimer(fctx);
7327 if (result != ISC_R_SUCCESS)
7328 fctx_done(fctx, result, __LINE__);
7329 } else if (result == DNS_R_CHASEDSSERVERS) {
7331 add_bad(fctx, addrinfo, result, broken_type);
7332 fctx_cancelqueries(fctx, ISC_TRUE);
7333 fctx_cleanupfinds(fctx);
7334 fctx_cleanupforwaddrs(fctx);
7336 n = dns_name_countlabels(&fctx->name);
7337 dns_name_getlabelsequence(&fctx->name, 1, n - 1, &fctx->nsname);
7339 FCTXTRACE("suspending DS lookup to find parent's NS records");
7341 result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
7343 NULL, NULL, NULL, 0, task,
7344 resume_dslookup, fctx,
7345 &fctx->nsrrset, NULL,
7347 if (result != ISC_R_SUCCESS)
7348 fctx_done(fctx, result, __LINE__);
7350 LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
7352 UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
7353 result = fctx_stopidletimer(fctx);
7354 if (result != ISC_R_SUCCESS)
7355 fctx_done(fctx, result, __LINE__);
7361 fctx_done(fctx, result, __LINE__);
7367 *** Resolver Methods
7370 destroy_badcache(dns_resolver_t *res) {
7371 dns_badcache_t *bad, *next;
7374 if (res->badcache != NULL) {
7375 for (i = 0; i < res->badhash; i++)
7376 for (bad = res->badcache[i]; bad != NULL;
7379 isc_mem_put(res->mctx, bad, sizeof(*bad) +
7383 isc_mem_put(res->mctx, res->badcache,
7384 sizeof(*res->badcache) * res->badhash);
7385 res->badcache = NULL;
7387 INSIST(res->badcount == 0);
7392 destroy(dns_resolver_t *res) {
7396 REQUIRE(res->references == 0);
7397 REQUIRE(!res->priming);
7398 REQUIRE(res->primefetch == NULL);
7402 INSIST(res->nfctx == 0);
7404 DESTROYLOCK(&res->primelock);
7405 DESTROYLOCK(&res->nlock);
7406 DESTROYLOCK(&res->lock);
7407 for (i = 0; i < res->nbuckets; i++) {
7408 INSIST(ISC_LIST_EMPTY(res->buckets[i].fctxs));
7409 isc_task_shutdown(res->buckets[i].task);
7410 isc_task_detach(&res->buckets[i].task);
7411 DESTROYLOCK(&res->buckets[i].lock);
7412 isc_mem_detach(&res->buckets[i].mctx);
7414 isc_mem_put(res->mctx, res->buckets,
7415 res->nbuckets * sizeof(fctxbucket_t));
7416 if (res->dispatchv4 != NULL)
7417 dns_dispatch_detach(&res->dispatchv4);
7418 if (res->dispatchv6 != NULL)
7419 dns_dispatch_detach(&res->dispatchv6);
7420 while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) {
7421 ISC_LIST_UNLINK(res->alternates, a, link);
7423 dns_name_free(&a->_u._n.name, res->mctx);
7424 isc_mem_put(res->mctx, a, sizeof(*a));
7426 dns_resolver_reset_algorithms(res);
7427 destroy_badcache(res);
7428 dns_resolver_resetmustbesecure(res);
7430 isc_rwlock_destroy(&res->alglock);
7433 isc_rwlock_destroy(&res->mbslock);
7435 isc_timer_detach(&res->spillattimer);
7437 isc_mem_put(res->mctx, res, sizeof(*res));
7441 send_shutdown_events(dns_resolver_t *res) {
7442 isc_event_t *event, *next_event;
7446 * Caller must be holding the resolver lock.
7449 for (event = ISC_LIST_HEAD(res->whenshutdown);
7451 event = next_event) {
7452 next_event = ISC_LIST_NEXT(event, ev_link);
7453 ISC_LIST_UNLINK(res->whenshutdown, event, ev_link);
7454 etask = event->ev_sender;
7455 event->ev_sender = res;
7456 isc_task_sendanddetach(&etask, &event);
7461 empty_bucket(dns_resolver_t *res) {
7462 RTRACE("empty_bucket");
7466 INSIST(res->activebuckets > 0);
7467 res->activebuckets--;
7468 if (res->activebuckets == 0)
7469 send_shutdown_events(res);
7475 spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
7476 dns_resolver_t *res = event->ev_arg;
7477 isc_result_t result;
7479 isc_boolean_t logit = ISC_FALSE;
7481 REQUIRE(VALID_RESOLVER(res));
7486 INSIST(!res->exiting);
7487 if (res->spillat > res->spillatmin) {
7491 if (res->spillat <= res->spillatmin) {
7492 result = isc_timer_reset(res->spillattimer,
7493 isc_timertype_inactive, NULL,
7495 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7497 count = res->spillat;
7500 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
7501 DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
7502 "clients-per-query decreased to %u", count);
7504 isc_event_free(&event);
7508 dns_resolver_create(dns_view_t *view,
7509 isc_taskmgr_t *taskmgr, unsigned int ntasks,
7510 isc_socketmgr_t *socketmgr,
7511 isc_timermgr_t *timermgr,
7512 unsigned int options,
7513 dns_dispatchmgr_t *dispatchmgr,
7514 dns_dispatch_t *dispatchv4,
7515 dns_dispatch_t *dispatchv6,
7516 dns_resolver_t **resp)
7518 dns_resolver_t *res;
7519 isc_result_t result = ISC_R_SUCCESS;
7520 unsigned int i, buckets_created = 0;
7521 isc_task_t *task = NULL;
7526 * Create a resolver.
7529 REQUIRE(DNS_VIEW_VALID(view));
7530 REQUIRE(ntasks > 0);
7531 REQUIRE(resp != NULL && *resp == NULL);
7532 REQUIRE(dispatchmgr != NULL);
7533 REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
7535 res = isc_mem_get(view->mctx, sizeof(*res));
7537 return (ISC_R_NOMEMORY);
7539 res->mctx = view->mctx;
7540 res->rdclass = view->rdclass;
7541 res->socketmgr = socketmgr;
7542 res->timermgr = timermgr;
7543 res->taskmgr = taskmgr;
7544 res->dispatchmgr = dispatchmgr;
7546 res->options = options;
7548 ISC_LIST_INIT(res->alternates);
7549 res->udpsize = RECV_BUFFER_SIZE;
7550 res->algorithms = NULL;
7551 res->badcache = NULL;
7555 res->mustbesecure = NULL;
7556 res->spillatmin = res->spillat = 10;
7557 res->spillatmax = 100;
7558 res->spillattimer = NULL;
7559 res->zero_no_soa_ttl = ISC_FALSE;
7560 res->query_timeout = DEFAULT_QUERY_TIMEOUT;
7562 res->nextdisp = 0; /* meaningless at this point, but init it */
7563 res->maxdepth = DEFAULT_RECURSION_DEPTH;
7564 res->maxqueries = DEFAULT_MAX_QUERIES;
7565 res->nbuckets = ntasks;
7566 res->activebuckets = ntasks;
7567 res->buckets = isc_mem_get(view->mctx,
7568 ntasks * sizeof(fctxbucket_t));
7569 if (res->buckets == NULL) {
7570 result = ISC_R_NOMEMORY;
7573 for (i = 0; i < ntasks; i++) {
7574 result = isc_mutex_init(&res->buckets[i].lock);
7575 if (result != ISC_R_SUCCESS)
7576 goto cleanup_buckets;
7577 res->buckets[i].task = NULL;
7578 result = isc_task_create(taskmgr, 0, &res->buckets[i].task);
7579 if (result != ISC_R_SUCCESS) {
7580 DESTROYLOCK(&res->buckets[i].lock);
7581 goto cleanup_buckets;
7583 res->buckets[i].mctx = NULL;
7584 snprintf(name, sizeof(name), "res%u", i);
7585 #ifdef ISC_PLATFORM_USETHREADS
7587 * Use a separate memory context for each bucket to reduce
7588 * contention among multiple threads. Do this only when
7589 * enabling threads because it will be require more memory.
7591 result = isc_mem_create(0, 0, &res->buckets[i].mctx);
7592 if (result != ISC_R_SUCCESS) {
7593 isc_task_detach(&res->buckets[i].task);
7594 DESTROYLOCK(&res->buckets[i].lock);
7595 goto cleanup_buckets;
7597 isc_mem_setname(res->buckets[i].mctx, name, NULL);
7599 isc_mem_attach(view->mctx, &res->buckets[i].mctx);
7601 isc_task_setname(res->buckets[i].task, name, res);
7602 ISC_LIST_INIT(res->buckets[i].fctxs);
7603 res->buckets[i].exiting = ISC_FALSE;
7607 res->dispatchv4 = NULL;
7608 if (dispatchv4 != NULL) {
7609 dns_dispatch_attach(dispatchv4, &res->dispatchv4);
7610 dispattr = dns_dispatch_getattributes(dispatchv4);
7612 ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0);
7615 res->dispatchv6 = NULL;
7616 if (dispatchv6 != NULL) {
7617 dns_dispatch_attach(dispatchv6, &res->dispatchv6);
7618 dispattr = dns_dispatch_getattributes(dispatchv6);
7620 ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0);
7623 res->references = 1;
7624 res->exiting = ISC_FALSE;
7625 res->frozen = ISC_FALSE;
7626 ISC_LIST_INIT(res->whenshutdown);
7627 res->priming = ISC_FALSE;
7628 res->primefetch = NULL;
7631 result = isc_mutex_init(&res->lock);
7632 if (result != ISC_R_SUCCESS)
7633 goto cleanup_dispatches;
7635 result = isc_mutex_init(&res->nlock);
7636 if (result != ISC_R_SUCCESS)
7639 result = isc_mutex_init(&res->primelock);
7640 if (result != ISC_R_SUCCESS)
7644 result = isc_task_create(taskmgr, 0, &task);
7645 if (result != ISC_R_SUCCESS)
7646 goto cleanup_primelock;
7648 result = isc_timer_create(timermgr, isc_timertype_inactive, NULL, NULL,
7649 task, spillattimer_countdown, res,
7650 &res->spillattimer);
7651 isc_task_detach(&task);
7652 if (result != ISC_R_SUCCESS)
7653 goto cleanup_primelock;
7656 result = isc_rwlock_init(&res->alglock, 0, 0);
7657 if (result != ISC_R_SUCCESS)
7658 goto cleanup_spillattimer;
7661 result = isc_rwlock_init(&res->mbslock, 0, 0);
7662 if (result != ISC_R_SUCCESS)
7663 goto cleanup_alglock;
7666 res->magic = RES_MAGIC;
7670 return (ISC_R_SUCCESS);
7675 isc_rwlock_destroy(&res->alglock);
7678 #if USE_ALGLOCK || USE_MBSLOCK
7679 cleanup_spillattimer:
7680 isc_timer_detach(&res->spillattimer);
7684 DESTROYLOCK(&res->primelock);
7687 DESTROYLOCK(&res->nlock);
7690 DESTROYLOCK(&res->lock);
7693 if (res->dispatchv6 != NULL)
7694 dns_dispatch_detach(&res->dispatchv6);
7695 if (res->dispatchv4 != NULL)
7696 dns_dispatch_detach(&res->dispatchv4);
7699 for (i = 0; i < buckets_created; i++) {
7700 isc_mem_detach(&res->buckets[i].mctx);
7701 DESTROYLOCK(&res->buckets[i].lock);
7702 isc_task_shutdown(res->buckets[i].task);
7703 isc_task_detach(&res->buckets[i].task);
7705 isc_mem_put(view->mctx, res->buckets,
7706 res->nbuckets * sizeof(fctxbucket_t));
7709 isc_mem_put(view->mctx, res, sizeof(*res));
7716 prime_done(isc_task_t *task, isc_event_t *event) {
7717 dns_resolver_t *res;
7718 dns_fetchevent_t *fevent;
7720 dns_db_t *db = NULL;
7722 REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
7723 fevent = (dns_fetchevent_t *)event;
7724 res = event->ev_arg;
7725 REQUIRE(VALID_RESOLVER(res));
7731 INSIST(res->priming);
7732 res->priming = ISC_FALSE;
7733 LOCK(&res->primelock);
7734 fetch = res->primefetch;
7735 res->primefetch = NULL;
7736 UNLOCK(&res->primelock);
7740 if (fevent->result == ISC_R_SUCCESS &&
7741 res->view->cache != NULL && res->view->hints != NULL) {
7742 dns_cache_attachdb(res->view->cache, &db);
7743 dns_root_checkhints(res->view, res->view->hints, db);
7747 if (fevent->node != NULL)
7748 dns_db_detachnode(fevent->db, &fevent->node);
7749 if (fevent->db != NULL)
7750 dns_db_detach(&fevent->db);
7751 if (dns_rdataset_isassociated(fevent->rdataset))
7752 dns_rdataset_disassociate(fevent->rdataset);
7753 INSIST(fevent->sigrdataset == NULL);
7755 isc_mem_put(res->mctx, fevent->rdataset, sizeof(*fevent->rdataset));
7757 isc_event_free(&event);
7758 dns_resolver_destroyfetch(&fetch);
7762 dns_resolver_prime(dns_resolver_t *res) {
7763 isc_boolean_t want_priming = ISC_FALSE;
7764 dns_rdataset_t *rdataset;
7765 isc_result_t result;
7767 REQUIRE(VALID_RESOLVER(res));
7768 REQUIRE(res->frozen);
7770 RTRACE("dns_resolver_prime");
7774 if (!res->exiting && !res->priming) {
7775 INSIST(res->primefetch == NULL);
7776 res->priming = ISC_TRUE;
7777 want_priming = ISC_TRUE;
7784 * To avoid any possible recursive locking problems, we
7785 * start the priming fetch like any other fetch, and holding
7786 * no resolver locks. No one else will try to start it
7787 * because we're the ones who set res->priming to true.
7788 * Any other callers of dns_resolver_prime() while we're
7789 * running will see that res->priming is already true and
7793 rdataset = isc_mem_get(res->mctx, sizeof(*rdataset));
7794 if (rdataset == NULL) {
7796 INSIST(res->priming);
7797 INSIST(res->primefetch == NULL);
7798 res->priming = ISC_FALSE;
7802 dns_rdataset_init(rdataset);
7803 LOCK(&res->primelock);
7804 result = dns_resolver_createfetch(res, dns_rootname,
7806 NULL, NULL, NULL, 0,
7807 res->buckets[0].task,
7809 res, rdataset, NULL,
7811 UNLOCK(&res->primelock);
7812 if (result != ISC_R_SUCCESS) {
7814 INSIST(res->priming);
7815 res->priming = ISC_FALSE;
7823 dns_resolver_freeze(dns_resolver_t *res) {
7828 REQUIRE(VALID_RESOLVER(res));
7830 res->frozen = ISC_TRUE;
7834 dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) {
7835 REQUIRE(VALID_RESOLVER(source));
7836 REQUIRE(targetp != NULL && *targetp == NULL);
7838 RRTRACE(source, "attach");
7839 LOCK(&source->lock);
7840 REQUIRE(!source->exiting);
7842 INSIST(source->references > 0);
7843 source->references++;
7844 INSIST(source->references != 0);
7845 UNLOCK(&source->lock);
7851 dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
7852 isc_event_t **eventp)
7857 REQUIRE(VALID_RESOLVER(res));
7858 REQUIRE(eventp != NULL);
7865 if (res->exiting && res->activebuckets == 0) {
7867 * We're already shutdown. Send the event.
7869 event->ev_sender = res;
7870 isc_task_send(task, &event);
7873 isc_task_attach(task, &clone);
7874 event->ev_sender = clone;
7875 ISC_LIST_APPEND(res->whenshutdown, event, ev_link);
7882 dns_resolver_shutdown(dns_resolver_t *res) {
7886 isc_result_t result;
7888 REQUIRE(VALID_RESOLVER(res));
7894 if (!res->exiting) {
7896 res->exiting = ISC_TRUE;
7898 for (i = 0; i < res->nbuckets; i++) {
7899 LOCK(&res->buckets[i].lock);
7900 for (fctx = ISC_LIST_HEAD(res->buckets[i].fctxs);
7902 fctx = ISC_LIST_NEXT(fctx, link))
7903 fctx_shutdown(fctx);
7904 if (res->dispatchv4 != NULL && !res->exclusivev4) {
7905 sock = dns_dispatch_getsocket(res->dispatchv4);
7906 isc_socket_cancel(sock, res->buckets[i].task,
7907 ISC_SOCKCANCEL_ALL);
7909 if (res->dispatchv6 != NULL && !res->exclusivev6) {
7910 sock = dns_dispatch_getsocket(res->dispatchv6);
7911 isc_socket_cancel(sock, res->buckets[i].task,
7912 ISC_SOCKCANCEL_ALL);
7914 res->buckets[i].exiting = ISC_TRUE;
7915 if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) {
7916 INSIST(res->activebuckets > 0);
7917 res->activebuckets--;
7919 UNLOCK(&res->buckets[i].lock);
7921 if (res->activebuckets == 0)
7922 send_shutdown_events(res);
7923 result = isc_timer_reset(res->spillattimer,
7924 isc_timertype_inactive, NULL,
7926 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7933 dns_resolver_detach(dns_resolver_t **resp) {
7934 dns_resolver_t *res;
7935 isc_boolean_t need_destroy = ISC_FALSE;
7937 REQUIRE(resp != NULL);
7939 REQUIRE(VALID_RESOLVER(res));
7945 INSIST(res->references > 0);
7947 if (res->references == 0) {
7948 INSIST(res->exiting && res->activebuckets == 0);
7949 need_destroy = ISC_TRUE;
7960 static inline isc_boolean_t
7961 fctx_match(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
7962 unsigned int options)
7965 * Don't match fetch contexts that are shutting down.
7967 if (fctx->cloned || fctx->state == fetchstate_done ||
7968 ISC_LIST_EMPTY(fctx->events))
7971 if (fctx->type != type || fctx->options != options)
7973 return (dns_name_equal(&fctx->name, name));
7977 log_fetch(dns_name_t *name, dns_rdatatype_t type) {
7978 char namebuf[DNS_NAME_FORMATSIZE];
7979 char typebuf[DNS_RDATATYPE_FORMATSIZE];
7980 int level = ISC_LOG_DEBUG(1);
7982 if (! isc_log_wouldlog(dns_lctx, level))
7985 dns_name_format(name, namebuf, sizeof(namebuf));
7986 dns_rdatatype_format(type, typebuf, sizeof(typebuf));
7988 isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
7989 DNS_LOGMODULE_RESOLVER, level,
7990 "createfetch: %s %s", namebuf, typebuf);
7994 dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name,
7995 dns_rdatatype_t type,
7996 dns_name_t *domain, dns_rdataset_t *nameservers,
7997 dns_forwarders_t *forwarders,
7998 unsigned int options, isc_task_t *task,
7999 isc_taskaction_t action, void *arg,
8000 dns_rdataset_t *rdataset,
8001 dns_rdataset_t *sigrdataset,
8002 dns_fetch_t **fetchp)
8004 return (dns_resolver_createfetch3(res, name, type, domain,
8005 nameservers, forwarders, NULL, 0,
8006 options, 0, NULL, task, action, arg,
8007 rdataset, sigrdataset, fetchp));
8011 dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name,
8012 dns_rdatatype_t type,
8013 dns_name_t *domain, dns_rdataset_t *nameservers,
8014 dns_forwarders_t *forwarders,
8015 isc_sockaddr_t *client, dns_messageid_t id,
8016 unsigned int options, isc_task_t *task,
8017 isc_taskaction_t action, void *arg,
8018 dns_rdataset_t *rdataset,
8019 dns_rdataset_t *sigrdataset,
8020 dns_fetch_t **fetchp)
8022 return (dns_resolver_createfetch3(res, name, type, domain,
8023 nameservers, forwarders, client, id,
8024 options, 0, NULL, task, action, arg,
8025 rdataset, sigrdataset, fetchp));
8029 dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name,
8030 dns_rdatatype_t type,
8031 dns_name_t *domain, dns_rdataset_t *nameservers,
8032 dns_forwarders_t *forwarders,
8033 isc_sockaddr_t *client, dns_messageid_t id,
8034 unsigned int options, unsigned int depth,
8035 isc_counter_t *qc, isc_task_t *task,
8036 isc_taskaction_t action, void *arg,
8037 dns_rdataset_t *rdataset,
8038 dns_rdataset_t *sigrdataset,
8039 dns_fetch_t **fetchp)
8042 fetchctx_t *fctx = NULL;
8043 isc_result_t result = ISC_R_SUCCESS;
8044 unsigned int bucketnum;
8045 isc_boolean_t new_fctx = ISC_FALSE;
8047 unsigned int count = 0;
8048 unsigned int spillat;
8049 unsigned int spillatmin;
8050 isc_boolean_t destroy = ISC_FALSE;
8054 REQUIRE(VALID_RESOLVER(res));
8055 REQUIRE(res->frozen);
8056 /* XXXRTH Check for meta type */
8057 if (domain != NULL) {
8058 REQUIRE(DNS_RDATASET_VALID(nameservers));
8059 REQUIRE(nameservers->type == dns_rdatatype_ns);
8061 REQUIRE(nameservers == NULL);
8062 REQUIRE(forwarders == NULL);
8063 REQUIRE(!dns_rdataset_isassociated(rdataset));
8064 REQUIRE(sigrdataset == NULL ||
8065 !dns_rdataset_isassociated(sigrdataset));
8066 REQUIRE(fetchp != NULL && *fetchp == NULL);
8068 log_fetch(name, type);
8071 * XXXRTH use a mempool?
8073 fetch = isc_mem_get(res->mctx, sizeof(*fetch));
8075 return (ISC_R_NOMEMORY);
8077 bucketnum = dns_name_fullhash(name, ISC_FALSE) % res->nbuckets;
8080 spillat = res->spillat;
8081 spillatmin = res->spillatmin;
8083 LOCK(&res->buckets[bucketnum].lock);
8085 if (res->buckets[bucketnum].exiting) {
8086 result = ISC_R_SHUTTINGDOWN;
8090 if ((options & DNS_FETCHOPT_UNSHARED) == 0) {
8091 for (fctx = ISC_LIST_HEAD(res->buckets[bucketnum].fctxs);
8093 fctx = ISC_LIST_NEXT(fctx, link)) {
8094 if (fctx_match(fctx, name, type, options))
8100 * Is this a duplicate?
8102 if (fctx != NULL && client != NULL) {
8103 dns_fetchevent_t *fevent;
8104 for (fevent = ISC_LIST_HEAD(fctx->events);
8106 fevent = ISC_LIST_NEXT(fevent, ev_link)) {
8107 if (fevent->client != NULL && fevent->id == id &&
8108 isc_sockaddr_equal(fevent->client, client)) {
8109 result = DNS_R_DUPLICATE;
8115 if (count >= spillatmin && spillatmin != 0) {
8116 INSIST(fctx != NULL);
8117 if (count >= spillat)
8118 fctx->spilled = ISC_TRUE;
8119 if (fctx->spilled) {
8120 result = DNS_R_DROP;
8126 result = fctx_create(res, name, type, domain, nameservers,
8127 options, bucketnum, depth, qc, &fctx);
8128 if (result != ISC_R_SUCCESS)
8130 new_fctx = ISC_TRUE;
8131 } else if (fctx->depth > depth)
8132 fctx->depth = depth;
8134 result = fctx_join(fctx, task, client, id, action, arg,
8135 rdataset, sigrdataset, fetch);
8137 if (result == ISC_R_SUCCESS) {
8141 event = &fctx->control_event;
8142 ISC_EVENT_INIT(event, sizeof(*event), 0, NULL,
8143 DNS_EVENT_FETCHCONTROL,
8144 fctx_start, fctx, NULL,
8146 isc_task_send(res->buckets[bucketnum].task, &event);
8149 * We don't care about the result of fctx_unlink()
8150 * since we know we're not exiting.
8152 (void)fctx_unlink(fctx);
8158 UNLOCK(&res->buckets[bucketnum].lock);
8163 if (result == ISC_R_SUCCESS) {
8167 isc_mem_put(res->mctx, fetch, sizeof(*fetch));
8173 dns_resolver_cancelfetch(dns_fetch_t *fetch) {
8175 dns_resolver_t *res;
8176 dns_fetchevent_t *event, *next_event;
8179 REQUIRE(DNS_FETCH_VALID(fetch));
8180 fctx = fetch->private;
8181 REQUIRE(VALID_FCTX(fctx));
8184 FTRACE("cancelfetch");
8186 LOCK(&res->buckets[fctx->bucketnum].lock);
8189 * Find the completion event for this fetch (as opposed
8190 * to those for other fetches that have joined the same
8191 * fctx) and send it with result = ISC_R_CANCELED.
8194 if (fctx->state != fetchstate_done) {
8195 for (event = ISC_LIST_HEAD(fctx->events);
8197 event = next_event) {
8198 next_event = ISC_LIST_NEXT(event, ev_link);
8199 if (event->fetch == fetch) {
8200 ISC_LIST_UNLINK(fctx->events, event, ev_link);
8205 if (event != NULL) {
8206 etask = event->ev_sender;
8207 event->ev_sender = fctx;
8208 event->result = ISC_R_CANCELED;
8209 isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event));
8212 * The fctx continues running even if no fetches remain;
8213 * the answer is still cached.
8216 UNLOCK(&res->buckets[fctx->bucketnum].lock);
8220 dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
8222 dns_resolver_t *res;
8223 dns_fetchevent_t *event, *next_event;
8225 unsigned int bucketnum;
8226 isc_boolean_t bucket_empty;
8228 REQUIRE(fetchp != NULL);
8230 REQUIRE(DNS_FETCH_VALID(fetch));
8231 fctx = fetch->private;
8232 REQUIRE(VALID_FCTX(fctx));
8235 FTRACE("destroyfetch");
8237 bucketnum = fctx->bucketnum;
8238 LOCK(&res->buckets[bucketnum].lock);
8241 * Sanity check: the caller should have gotten its event before
8242 * trying to destroy the fetch.
8245 if (fctx->state != fetchstate_done) {
8246 for (event = ISC_LIST_HEAD(fctx->events);
8248 event = next_event) {
8249 next_event = ISC_LIST_NEXT(event, ev_link);
8250 RUNTIME_CHECK(event->fetch != fetch);
8254 bucket_empty = fctx_decreference(fctx);
8256 UNLOCK(&res->buckets[bucketnum].lock);
8258 isc_mem_put(res->mctx, fetch, sizeof(*fetch));
8266 dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx,
8267 isc_logcategory_t *category, isc_logmodule_t *module,
8268 int level, isc_boolean_t duplicateok)
8271 dns_resolver_t *res;
8272 char domainbuf[DNS_NAME_FORMATSIZE];
8274 REQUIRE(DNS_FETCH_VALID(fetch));
8275 fctx = fetch->private;
8276 REQUIRE(VALID_FCTX(fctx));
8279 LOCK(&res->buckets[fctx->bucketnum].lock);
8281 INSIST(fctx->exitline >= 0);
8282 if (!fctx->logged || duplicateok) {
8283 dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
8284 isc_log_write(lctx, category, module, level,
8285 "fetch completed at %s:%d for %s in "
8286 "%" ISC_PRINT_QUADFORMAT "u."
8287 "%06" ISC_PRINT_QUADFORMAT "u: %s/%s "
8288 "[domain:%s,referral:%u,restart:%u,qrysent:%u,"
8289 "timeout:%u,lame:%u,neterr:%u,badresp:%u,"
8290 "adberr:%u,findfail:%u,valfail:%u]",
8291 __FILE__, fctx->exitline, fctx->info,
8292 fctx->duration / 1000000,
8293 fctx->duration % 1000000,
8294 isc_result_totext(fctx->result),
8295 isc_result_totext(fctx->vresult), domainbuf,
8296 fctx->referrals, fctx->restarts,
8297 fctx->querysent, fctx->timeouts, fctx->lamecount,
8298 fctx->neterr, fctx->badresp, fctx->adberr,
8299 fctx->findfail, fctx->valfail);
8300 fctx->logged = ISC_TRUE;
8303 UNLOCK(&res->buckets[fctx->bucketnum].lock);
8307 dns_resolver_dispatchmgr(dns_resolver_t *resolver) {
8308 REQUIRE(VALID_RESOLVER(resolver));
8309 return (resolver->dispatchmgr);
8313 dns_resolver_dispatchv4(dns_resolver_t *resolver) {
8314 REQUIRE(VALID_RESOLVER(resolver));
8315 return (resolver->dispatchv4);
8319 dns_resolver_dispatchv6(dns_resolver_t *resolver) {
8320 REQUIRE(VALID_RESOLVER(resolver));
8321 return (resolver->dispatchv6);
8325 dns_resolver_socketmgr(dns_resolver_t *resolver) {
8326 REQUIRE(VALID_RESOLVER(resolver));
8327 return (resolver->socketmgr);
8331 dns_resolver_taskmgr(dns_resolver_t *resolver) {
8332 REQUIRE(VALID_RESOLVER(resolver));
8333 return (resolver->taskmgr);
8337 dns_resolver_getlamettl(dns_resolver_t *resolver) {
8338 REQUIRE(VALID_RESOLVER(resolver));
8339 return (resolver->lame_ttl);
8343 dns_resolver_setlamettl(dns_resolver_t *resolver, isc_uint32_t lame_ttl) {
8344 REQUIRE(VALID_RESOLVER(resolver));
8345 resolver->lame_ttl = lame_ttl;
8349 dns_resolver_nrunning(dns_resolver_t *resolver) {
8351 LOCK(&resolver->nlock);
8352 n = resolver->nfctx;
8353 UNLOCK(&resolver->nlock);
8358 dns_resolver_addalternate(dns_resolver_t *resolver, isc_sockaddr_t *alt,
8359 dns_name_t *name, in_port_t port) {
8361 isc_result_t result;
8363 REQUIRE(VALID_RESOLVER(resolver));
8364 REQUIRE(!resolver->frozen);
8365 REQUIRE((alt == NULL) ^ (name == NULL));
8367 a = isc_mem_get(resolver->mctx, sizeof(*a));
8369 return (ISC_R_NOMEMORY);
8371 a->isaddress = ISC_TRUE;
8374 a->isaddress = ISC_FALSE;
8375 a->_u._n.port = port;
8376 dns_name_init(&a->_u._n.name, NULL);
8377 result = dns_name_dup(name, resolver->mctx, &a->_u._n.name);
8378 if (result != ISC_R_SUCCESS) {
8379 isc_mem_put(resolver->mctx, a, sizeof(*a));
8383 ISC_LINK_INIT(a, link);
8384 ISC_LIST_APPEND(resolver->alternates, a, link);
8386 return (ISC_R_SUCCESS);
8390 dns_resolver_setudpsize(dns_resolver_t *resolver, isc_uint16_t udpsize) {
8391 REQUIRE(VALID_RESOLVER(resolver));
8392 resolver->udpsize = udpsize;
8396 dns_resolver_getudpsize(dns_resolver_t *resolver) {
8397 REQUIRE(VALID_RESOLVER(resolver));
8398 return (resolver->udpsize);
8402 dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) {
8404 dns_badcache_t *bad, *prev, *next;
8406 REQUIRE(VALID_RESOLVER(resolver));
8408 LOCK(&resolver->lock);
8409 if (resolver->badcache == NULL)
8414 isc_result_t result;
8415 result = isc_time_now(&now);
8416 if (result != ISC_R_SUCCESS)
8417 isc_time_settoepoch(&now);
8418 i = dns_name_hash(name, ISC_FALSE) % resolver->badhash;
8420 for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
8423 n = isc_time_compare(&bad->expire, &now);
8424 if (n < 0 || dns_name_equal(name, &bad->name)) {
8426 resolver->badcache[i] = bad->next;
8428 prev->next = bad->next;
8429 isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
8431 resolver->badcount--;
8436 destroy_badcache(resolver);
8439 UNLOCK(&resolver->lock);
8444 resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) {
8445 unsigned int newsize;
8446 dns_badcache_t **new, *bad, *next;
8450 newsize = resolver->badhash * 2 + 1;
8452 newsize = (resolver->badhash - 1) / 2;
8454 new = isc_mem_get(resolver->mctx,
8455 sizeof(*resolver->badcache) * newsize);
8458 memset(new, 0, sizeof(*resolver->badcache) * newsize);
8459 for (i = 0; i < resolver->badhash; i++) {
8460 for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
8462 if (isc_time_compare(&bad->expire, now) < 0) {
8463 isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
8465 resolver->badcount--;
8467 bad->next = new[bad->hashval % newsize];
8468 new[bad->hashval % newsize] = bad;
8472 isc_mem_put(resolver->mctx, resolver->badcache,
8473 sizeof(*resolver->badcache) * resolver->badhash);
8474 resolver->badhash = newsize;
8475 resolver->badcache = new;
8479 dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
8480 dns_rdatatype_t type, isc_time_t *expire)
8483 isc_result_t result = ISC_R_SUCCESS;
8484 unsigned int i, hashval;
8485 dns_badcache_t *bad, *prev, *next;
8487 REQUIRE(VALID_RESOLVER(resolver));
8489 LOCK(&resolver->lock);
8490 if (resolver->badcache == NULL) {
8491 resolver->badcache = isc_mem_get(resolver->mctx,
8492 sizeof(*resolver->badcache) *
8494 if (resolver->badcache == NULL)
8496 resolver->badhash = DNS_BADCACHE_SIZE;
8497 memset(resolver->badcache, 0, sizeof(*resolver->badcache) *
8501 result = isc_time_now(&now);
8502 if (result != ISC_R_SUCCESS)
8503 isc_time_settoepoch(&now);
8504 hashval = dns_name_hash(name, ISC_FALSE);
8505 i = hashval % resolver->badhash;
8507 for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
8509 if (bad->type == type && dns_name_equal(name, &bad->name))
8511 if (isc_time_compare(&bad->expire, &now) < 0) {
8513 resolver->badcache[i] = bad->next;
8515 prev->next = bad->next;
8516 isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
8518 resolver->badcount--;
8523 isc_buffer_t buffer;
8524 bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length);
8528 bad->hashval = hashval;
8529 bad->expire = *expire;
8530 isc_buffer_init(&buffer, bad + 1, name->length);
8531 dns_name_init(&bad->name, NULL);
8532 dns_name_copy(name, &bad->name, &buffer);
8533 bad->next = resolver->badcache[i];
8534 resolver->badcache[i] = bad;
8535 resolver->badcount++;
8536 if (resolver->badcount > resolver->badhash * 8)
8537 resizehash(resolver, &now, ISC_TRUE);
8538 if (resolver->badcount < resolver->badhash * 2 &&
8539 resolver->badhash > DNS_BADCACHE_SIZE)
8540 resizehash(resolver, &now, ISC_FALSE);
8542 bad->expire = *expire;
8544 UNLOCK(&resolver->lock);
8548 dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name,
8549 dns_rdatatype_t type, isc_time_t *now)
8551 dns_badcache_t *bad, *prev, *next;
8552 isc_boolean_t answer = ISC_FALSE;
8555 REQUIRE(VALID_RESOLVER(resolver));
8557 LOCK(&resolver->lock);
8558 if (resolver->badcache == NULL)
8561 i = dns_name_hash(name, ISC_FALSE) % resolver->badhash;
8563 for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
8566 * Search the hash list. Clean out expired records as we go.
8568 if (isc_time_compare(&bad->expire, now) < 0) {
8570 prev->next = bad->next;
8572 resolver->badcache[i] = bad->next;
8573 isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
8575 resolver->badcount--;
8578 if (bad->type == type && dns_name_equal(name, &bad->name)) {
8586 * Slow sweep to clean out stale records.
8588 i = resolver->badsweep++ % resolver->badhash;
8589 bad = resolver->badcache[i];
8590 if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) {
8591 resolver->badcache[i] = bad->next;
8592 isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
8594 resolver->badcount--;
8598 UNLOCK(&resolver->lock);
8603 dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) {
8604 char namebuf[DNS_NAME_FORMATSIZE];
8605 char typebuf[DNS_RDATATYPE_FORMATSIZE];
8606 dns_badcache_t *bad, *next, *prev;
8611 LOCK(&resolver->lock);
8612 fprintf(fp, ";\n; Bad cache\n;\n");
8614 if (resolver->badcache == NULL)
8618 for (i = 0; i < resolver->badhash; i++) {
8620 for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
8622 if (isc_time_compare(&bad->expire, &now) < 0) {
8624 prev->next = bad->next;
8626 resolver->badcache[i] = bad->next;
8627 isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
8629 resolver->badcount--;
8633 dns_name_format(&bad->name, namebuf, sizeof(namebuf));
8634 dns_rdatatype_format(bad->type, typebuf,
8636 t = isc_time_microdiff(&bad->expire, &now);
8638 fprintf(fp, "; %s/%s [ttl "
8639 "%" ISC_PLATFORM_QUADFORMAT "u]\n",
8640 namebuf, typebuf, t);
8645 UNLOCK(&resolver->lock);
8649 free_algorithm(void *node, void *arg) {
8650 unsigned char *algorithms = node;
8651 isc_mem_t *mctx = arg;
8653 isc_mem_put(mctx, algorithms, *algorithms);
8657 dns_resolver_reset_algorithms(dns_resolver_t *resolver) {
8659 REQUIRE(VALID_RESOLVER(resolver));
8662 RWLOCK(&resolver->alglock, isc_rwlocktype_write);
8664 if (resolver->algorithms != NULL)
8665 dns_rbt_destroy(&resolver->algorithms);
8667 RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
8672 dns_resolver_disable_algorithm(dns_resolver_t *resolver, dns_name_t *name,
8675 unsigned int len, mask;
8677 unsigned char *algorithms;
8678 isc_result_t result;
8679 dns_rbtnode_t *node = NULL;
8681 REQUIRE(VALID_RESOLVER(resolver));
8683 return (ISC_R_RANGE);
8686 RWLOCK(&resolver->alglock, isc_rwlocktype_write);
8688 if (resolver->algorithms == NULL) {
8689 result = dns_rbt_create(resolver->mctx, free_algorithm,
8690 resolver->mctx, &resolver->algorithms);
8691 if (result != ISC_R_SUCCESS)
8696 mask = 1 << (alg%8);
8698 result = dns_rbt_addnode(resolver->algorithms, name, &node);
8700 if (result == ISC_R_SUCCESS || result == ISC_R_EXISTS) {
8701 algorithms = node->data;
8702 if (algorithms == NULL || len > *algorithms) {
8703 new = isc_mem_get(resolver->mctx, len);
8705 result = ISC_R_NOMEMORY;
8708 memset(new, 0, len);
8709 if (algorithms != NULL)
8710 memcpy(new, algorithms, *algorithms);
8714 if (algorithms != NULL)
8715 isc_mem_put(resolver->mctx, algorithms,
8718 algorithms[len-1] |= mask;
8720 result = ISC_R_SUCCESS;
8723 RWUNLOCK(&resolver->alglock, isc_rwlocktype_write);
8729 dns_resolver_algorithm_supported(dns_resolver_t *resolver, dns_name_t *name,
8732 unsigned int len, mask;
8733 unsigned char *algorithms;
8735 isc_result_t result;
8736 isc_boolean_t found = ISC_FALSE;
8738 REQUIRE(VALID_RESOLVER(resolver));
8741 RWLOCK(&resolver->alglock, isc_rwlocktype_read);
8743 if (resolver->algorithms == NULL)
8745 result = dns_rbt_findname(resolver->algorithms, name, 0, NULL, &data);
8746 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
8748 mask = 1 << (alg%8);
8750 if (len <= *algorithms && (algorithms[len-1] & mask) != 0)
8755 RWUNLOCK(&resolver->alglock, isc_rwlocktype_read);
8759 return (dst_algorithm_supported(alg));
8763 dns_resolver_digest_supported(dns_resolver_t *resolver, unsigned int digest) {
8766 return (dns_ds_digest_supported(digest));
8770 dns_resolver_resetmustbesecure(dns_resolver_t *resolver) {
8772 REQUIRE(VALID_RESOLVER(resolver));
8775 RWLOCK(&resolver->mbslock, isc_rwlocktype_write);
8777 if (resolver->mustbesecure != NULL)
8778 dns_rbt_destroy(&resolver->mustbesecure);
8780 RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write);
8784 static isc_boolean_t yes = ISC_TRUE, no = ISC_FALSE;
8787 dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name,
8788 isc_boolean_t value)
8790 isc_result_t result;
8792 REQUIRE(VALID_RESOLVER(resolver));
8795 RWLOCK(&resolver->mbslock, isc_rwlocktype_write);
8797 if (resolver->mustbesecure == NULL) {
8798 result = dns_rbt_create(resolver->mctx, NULL, NULL,
8799 &resolver->mustbesecure);
8800 if (result != ISC_R_SUCCESS)
8803 result = dns_rbt_addname(resolver->mustbesecure, name,
8804 value ? &yes : &no);
8807 RWUNLOCK(&resolver->mbslock, isc_rwlocktype_write);
8813 dns_resolver_getmustbesecure(dns_resolver_t *resolver, dns_name_t *name) {
8815 isc_boolean_t value = ISC_FALSE;
8816 isc_result_t result;
8818 REQUIRE(VALID_RESOLVER(resolver));
8821 RWLOCK(&resolver->mbslock, isc_rwlocktype_read);
8823 if (resolver->mustbesecure == NULL)
8825 result = dns_rbt_findname(resolver->mustbesecure, name, 0, NULL, &data);
8826 if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
8827 value = *(isc_boolean_t*)data;
8830 RWUNLOCK(&resolver->mbslock, isc_rwlocktype_read);
8836 dns_resolver_getclientsperquery(dns_resolver_t *resolver, isc_uint32_t *cur,
8837 isc_uint32_t *min, isc_uint32_t *max)
8839 REQUIRE(VALID_RESOLVER(resolver));
8841 LOCK(&resolver->lock);
8843 *cur = resolver->spillat;
8845 *min = resolver->spillatmin;
8847 *max = resolver->spillatmax;
8848 UNLOCK(&resolver->lock);
8852 dns_resolver_setclientsperquery(dns_resolver_t *resolver, isc_uint32_t min,
8855 REQUIRE(VALID_RESOLVER(resolver));
8857 LOCK(&resolver->lock);
8858 resolver->spillatmin = resolver->spillat = min;
8859 resolver->spillatmax = max;
8860 UNLOCK(&resolver->lock);
8864 dns_resolver_getzeronosoattl(dns_resolver_t *resolver) {
8865 REQUIRE(VALID_RESOLVER(resolver));
8867 return (resolver->zero_no_soa_ttl);
8871 dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state) {
8872 REQUIRE(VALID_RESOLVER(resolver));
8874 resolver->zero_no_soa_ttl = state;
8878 dns_resolver_getoptions(dns_resolver_t *resolver) {
8879 REQUIRE(VALID_RESOLVER(resolver));
8881 return (resolver->options);
8885 dns_resolver_gettimeout(dns_resolver_t *resolver) {
8886 REQUIRE(VALID_RESOLVER(resolver));
8888 return (resolver->query_timeout);
8892 dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds) {
8893 REQUIRE(VALID_RESOLVER(resolver));
8896 seconds = DEFAULT_QUERY_TIMEOUT;
8897 if (seconds > MAXIMUM_QUERY_TIMEOUT)
8898 seconds = MAXIMUM_QUERY_TIMEOUT;
8900 resolver->query_timeout = seconds;
8904 dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth) {
8905 REQUIRE(VALID_RESOLVER(resolver));
8906 resolver->maxdepth = maxdepth;
8910 dns_resolver_getmaxdepth(dns_resolver_t *resolver) {
8911 REQUIRE(VALID_RESOLVER(resolver));
8912 return (resolver->maxdepth);
8916 dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) {
8917 REQUIRE(VALID_RESOLVER(resolver));
8918 resolver->maxqueries = queries;
8922 dns_resolver_getmaxqueries(dns_resolver_t *resolver) {
8923 REQUIRE(VALID_RESOLVER(resolver));
8924 return (resolver->maxqueries);