PageRenderTime 89ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 2ms

/contrib/bind9/lib/dns/resolver.c

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