/contrib/bind9/lib/dns/rdataset.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 774 lines · 561 code · 114 blank · 99 comment · 156 complexity · be56482ac199ac3717ae1918e9563d3a MD5 · raw file

  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 <stdlib.h>
  21. #include <isc/buffer.h>
  22. #include <isc/mem.h>
  23. #include <isc/random.h>
  24. #include <isc/util.h>
  25. #include <dns/name.h>
  26. #include <dns/ncache.h>
  27. #include <dns/rdata.h>
  28. #include <dns/rdataset.h>
  29. #include <dns/compress.h>
  30. static const char *trustnames[] = {
  31. "none",
  32. "pending-additional",
  33. "pending-answer",
  34. "additional",
  35. "glue",
  36. "answer",
  37. "authauthority",
  38. "authanswer",
  39. "secure",
  40. "local" /* aka ultimate */
  41. };
  42. const char *
  43. dns_trust_totext(dns_trust_t trust) {
  44. if (trust >= sizeof(trustnames)/sizeof(*trustnames))
  45. return ("bad");
  46. return (trustnames[trust]);
  47. }
  48. void
  49. dns_rdataset_init(dns_rdataset_t *rdataset) {
  50. /*
  51. * Make 'rdataset' a valid, disassociated rdataset.
  52. */
  53. REQUIRE(rdataset != NULL);
  54. rdataset->magic = DNS_RDATASET_MAGIC;
  55. rdataset->methods = NULL;
  56. ISC_LINK_INIT(rdataset, link);
  57. rdataset->rdclass = 0;
  58. rdataset->type = 0;
  59. rdataset->ttl = 0;
  60. rdataset->trust = 0;
  61. rdataset->covers = 0;
  62. rdataset->attributes = 0;
  63. rdataset->count = ISC_UINT32_MAX;
  64. rdataset->private1 = NULL;
  65. rdataset->private2 = NULL;
  66. rdataset->private3 = NULL;
  67. rdataset->privateuint4 = 0;
  68. rdataset->private5 = NULL;
  69. rdataset->private6 = NULL;
  70. rdataset->resign = 0;
  71. }
  72. void
  73. dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
  74. /*
  75. * Invalidate 'rdataset'.
  76. */
  77. REQUIRE(DNS_RDATASET_VALID(rdataset));
  78. REQUIRE(rdataset->methods == NULL);
  79. rdataset->magic = 0;
  80. ISC_LINK_INIT(rdataset, link);
  81. rdataset->rdclass = 0;
  82. rdataset->type = 0;
  83. rdataset->ttl = 0;
  84. rdataset->trust = 0;
  85. rdataset->covers = 0;
  86. rdataset->attributes = 0;
  87. rdataset->count = ISC_UINT32_MAX;
  88. rdataset->private1 = NULL;
  89. rdataset->private2 = NULL;
  90. rdataset->private3 = NULL;
  91. rdataset->privateuint4 = 0;
  92. rdataset->private5 = NULL;
  93. }
  94. void
  95. dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
  96. /*
  97. * Disassociate 'rdataset' from its rdata, allowing it to be reused.
  98. */
  99. REQUIRE(DNS_RDATASET_VALID(rdataset));
  100. REQUIRE(rdataset->methods != NULL);
  101. (rdataset->methods->disassociate)(rdataset);
  102. rdataset->methods = NULL;
  103. ISC_LINK_INIT(rdataset, link);
  104. rdataset->rdclass = 0;
  105. rdataset->type = 0;
  106. rdataset->ttl = 0;
  107. rdataset->trust = 0;
  108. rdataset->covers = 0;
  109. rdataset->attributes = 0;
  110. rdataset->count = ISC_UINT32_MAX;
  111. rdataset->private1 = NULL;
  112. rdataset->private2 = NULL;
  113. rdataset->private3 = NULL;
  114. rdataset->privateuint4 = 0;
  115. rdataset->private5 = NULL;
  116. rdataset->private6 = NULL;
  117. }
  118. isc_boolean_t
  119. dns_rdataset_isassociated(dns_rdataset_t *rdataset) {
  120. /*
  121. * Is 'rdataset' associated?
  122. */
  123. REQUIRE(DNS_RDATASET_VALID(rdataset));
  124. if (rdataset->methods != NULL)
  125. return (ISC_TRUE);
  126. return (ISC_FALSE);
  127. }
  128. static void
  129. question_disassociate(dns_rdataset_t *rdataset) {
  130. UNUSED(rdataset);
  131. }
  132. static isc_result_t
  133. question_cursor(dns_rdataset_t *rdataset) {
  134. UNUSED(rdataset);
  135. return (ISC_R_NOMORE);
  136. }
  137. static void
  138. question_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
  139. /*
  140. * This routine should never be called.
  141. */
  142. UNUSED(rdataset);
  143. UNUSED(rdata);
  144. REQUIRE(0);
  145. }
  146. static void
  147. question_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
  148. *target = *source;
  149. }
  150. static unsigned int
  151. question_count(dns_rdataset_t *rdataset) {
  152. /*
  153. * This routine should never be called.
  154. */
  155. UNUSED(rdataset);
  156. REQUIRE(0);
  157. return (0);
  158. }
  159. static dns_rdatasetmethods_t question_methods = {
  160. question_disassociate,
  161. question_cursor,
  162. question_cursor,
  163. question_current,
  164. question_clone,
  165. question_count,
  166. NULL,
  167. NULL,
  168. NULL,
  169. NULL,
  170. NULL,
  171. NULL,
  172. NULL,
  173. NULL,
  174. NULL
  175. };
  176. void
  177. dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
  178. dns_rdatatype_t type)
  179. {
  180. /*
  181. * Make 'rdataset' a valid, associated, question rdataset, with a
  182. * question class of 'rdclass' and type 'type'.
  183. */
  184. REQUIRE(DNS_RDATASET_VALID(rdataset));
  185. REQUIRE(rdataset->methods == NULL);
  186. rdataset->methods = &question_methods;
  187. rdataset->rdclass = rdclass;
  188. rdataset->type = type;
  189. rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
  190. }
  191. unsigned int
  192. dns_rdataset_count(dns_rdataset_t *rdataset) {
  193. /*
  194. * Return the number of records in 'rdataset'.
  195. */
  196. REQUIRE(DNS_RDATASET_VALID(rdataset));
  197. REQUIRE(rdataset->methods != NULL);
  198. return ((rdataset->methods->count)(rdataset));
  199. }
  200. void
  201. dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
  202. /*
  203. * Make 'target' refer to the same rdataset as 'source'.
  204. */
  205. REQUIRE(DNS_RDATASET_VALID(source));
  206. REQUIRE(source->methods != NULL);
  207. REQUIRE(DNS_RDATASET_VALID(target));
  208. REQUIRE(target->methods == NULL);
  209. (source->methods->clone)(source, target);
  210. }
  211. isc_result_t
  212. dns_rdataset_first(dns_rdataset_t *rdataset) {
  213. /*
  214. * Move the rdata cursor to the first rdata in the rdataset (if any).
  215. */
  216. REQUIRE(DNS_RDATASET_VALID(rdataset));
  217. REQUIRE(rdataset->methods != NULL);
  218. return ((rdataset->methods->first)(rdataset));
  219. }
  220. isc_result_t
  221. dns_rdataset_next(dns_rdataset_t *rdataset) {
  222. /*
  223. * Move the rdata cursor to the next rdata in the rdataset (if any).
  224. */
  225. REQUIRE(DNS_RDATASET_VALID(rdataset));
  226. REQUIRE(rdataset->methods != NULL);
  227. return ((rdataset->methods->next)(rdataset));
  228. }
  229. void
  230. dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
  231. /*
  232. * Make 'rdata' refer to the current rdata.
  233. */
  234. REQUIRE(DNS_RDATASET_VALID(rdataset));
  235. REQUIRE(rdataset->methods != NULL);
  236. (rdataset->methods->current)(rdataset, rdata);
  237. }
  238. #define MAX_SHUFFLE 32
  239. #define WANT_FIXED(r) (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
  240. #define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
  241. struct towire_sort {
  242. int key;
  243. dns_rdata_t *rdata;
  244. };
  245. static int
  246. towire_compare(const void *av, const void *bv) {
  247. const struct towire_sort *a = (const struct towire_sort *) av;
  248. const struct towire_sort *b = (const struct towire_sort *) bv;
  249. return (a->key - b->key);
  250. }
  251. static isc_result_t
  252. towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
  253. dns_compress_t *cctx, isc_buffer_t *target,
  254. dns_rdatasetorderfunc_t order, const void *order_arg,
  255. isc_boolean_t partial, unsigned int options,
  256. unsigned int *countp, void **state)
  257. {
  258. dns_rdata_t rdata = DNS_RDATA_INIT;
  259. isc_region_t r;
  260. isc_result_t result;
  261. unsigned int i, count = 0, added, choice;
  262. isc_buffer_t savedbuffer, rdlen, rrbuffer;
  263. unsigned int headlen;
  264. isc_boolean_t question = ISC_FALSE;
  265. isc_boolean_t shuffle = ISC_FALSE;
  266. dns_rdata_t *shuffled = NULL, shuffled_fixed[MAX_SHUFFLE];
  267. struct towire_sort *sorted = NULL, sorted_fixed[MAX_SHUFFLE];
  268. UNUSED(state);
  269. /*
  270. * Convert 'rdataset' to wire format, compressing names as specified
  271. * in cctx, and storing the result in 'target'.
  272. */
  273. REQUIRE(DNS_RDATASET_VALID(rdataset));
  274. REQUIRE(countp != NULL);
  275. REQUIRE((order == NULL) == (order_arg == NULL));
  276. REQUIRE(cctx != NULL && cctx->mctx != NULL);
  277. if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
  278. question = ISC_TRUE;
  279. count = 1;
  280. result = dns_rdataset_first(rdataset);
  281. INSIST(result == ISC_R_NOMORE);
  282. } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
  283. /*
  284. * This is a negative caching rdataset.
  285. */
  286. unsigned int ncache_opts = 0;
  287. if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0)
  288. ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC;
  289. return (dns_ncache_towire(rdataset, cctx, target, ncache_opts,
  290. countp));
  291. } else {
  292. count = (rdataset->methods->count)(rdataset);
  293. result = dns_rdataset_first(rdataset);
  294. if (result == ISC_R_NOMORE)
  295. return (ISC_R_SUCCESS);
  296. if (result != ISC_R_SUCCESS)
  297. return (result);
  298. }
  299. /*
  300. * Do we want to shuffle this answer?
  301. */
  302. if (!question && count > 1 &&
  303. (!WANT_FIXED(rdataset) || order != NULL) &&
  304. rdataset->type != dns_rdatatype_rrsig)
  305. shuffle = ISC_TRUE;
  306. if (shuffle && count > MAX_SHUFFLE) {
  307. shuffled = isc_mem_get(cctx->mctx, count * sizeof(*shuffled));
  308. sorted = isc_mem_get(cctx->mctx, count * sizeof(*sorted));
  309. if (shuffled == NULL || sorted == NULL)
  310. shuffle = ISC_FALSE;
  311. } else {
  312. shuffled = shuffled_fixed;
  313. sorted = sorted_fixed;
  314. }
  315. if (shuffle) {
  316. /*
  317. * First we get handles to all of the rdata.
  318. */
  319. i = 0;
  320. do {
  321. INSIST(i < count);
  322. dns_rdata_init(&shuffled[i]);
  323. dns_rdataset_current(rdataset, &shuffled[i]);
  324. i++;
  325. result = dns_rdataset_next(rdataset);
  326. } while (result == ISC_R_SUCCESS);
  327. if (result != ISC_R_NOMORE)
  328. goto cleanup;
  329. INSIST(i == count);
  330. /*
  331. * Now we shuffle.
  332. */
  333. if (WANT_FIXED(rdataset)) {
  334. /*
  335. * 'Fixed' order.
  336. */
  337. INSIST(order != NULL);
  338. for (i = 0; i < count; i++) {
  339. sorted[i].key = (*order)(&shuffled[i],
  340. order_arg);
  341. sorted[i].rdata = &shuffled[i];
  342. }
  343. } else if (WANT_RANDOM(rdataset)) {
  344. /*
  345. * 'Random' order.
  346. */
  347. for (i = 0; i < count; i++) {
  348. dns_rdata_t rdata;
  349. isc_uint32_t val;
  350. isc_random_get(&val);
  351. choice = i + (val % (count - i));
  352. rdata = shuffled[i];
  353. shuffled[i] = shuffled[choice];
  354. shuffled[choice] = rdata;
  355. if (order != NULL)
  356. sorted[i].key = (*order)(&shuffled[i],
  357. order_arg);
  358. else
  359. sorted[i].key = 0; /* Unused */
  360. sorted[i].rdata = &shuffled[i];
  361. }
  362. } else {
  363. /*
  364. * "Cyclic" order.
  365. */
  366. isc_uint32_t val;
  367. unsigned int j;
  368. val = rdataset->count;
  369. if (val == ISC_UINT32_MAX)
  370. isc_random_get(&val);
  371. j = val % count;
  372. for (i = 0; i < count; i++) {
  373. if (order != NULL)
  374. sorted[i].key = (*order)(&shuffled[j],
  375. order_arg);
  376. else
  377. sorted[i].key = 0; /* Unused */
  378. sorted[i].rdata = &shuffled[j];
  379. j++;
  380. if (j == count)
  381. j = 0; /* Wrap around. */
  382. }
  383. }
  384. /*
  385. * Sorted order.
  386. */
  387. if (order != NULL)
  388. qsort(sorted, count, sizeof(sorted[0]),
  389. towire_compare);
  390. }
  391. savedbuffer = *target;
  392. i = 0;
  393. added = 0;
  394. do {
  395. /*
  396. * Copy out the name, type, class, ttl.
  397. */
  398. rrbuffer = *target;
  399. dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
  400. result = dns_name_towire(owner_name, cctx, target);
  401. if (result != ISC_R_SUCCESS)
  402. goto rollback;
  403. headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
  404. if (!question)
  405. headlen += sizeof(dns_ttl_t)
  406. + 2; /* XXX 2 for rdata len */
  407. isc_buffer_availableregion(target, &r);
  408. if (r.length < headlen) {
  409. result = ISC_R_NOSPACE;
  410. goto rollback;
  411. }
  412. isc_buffer_putuint16(target, rdataset->type);
  413. isc_buffer_putuint16(target, rdataset->rdclass);
  414. if (!question) {
  415. isc_buffer_putuint32(target, rdataset->ttl);
  416. /*
  417. * Save space for rdlen.
  418. */
  419. rdlen = *target;
  420. isc_buffer_add(target, 2);
  421. /*
  422. * Copy out the rdata
  423. */
  424. if (shuffle)
  425. rdata = *(sorted[i].rdata);
  426. else {
  427. dns_rdata_reset(&rdata);
  428. dns_rdataset_current(rdataset, &rdata);
  429. }
  430. result = dns_rdata_towire(&rdata, cctx, target);
  431. if (result != ISC_R_SUCCESS)
  432. goto rollback;
  433. INSIST((target->used >= rdlen.used + 2) &&
  434. (target->used - rdlen.used - 2 < 65536));
  435. isc_buffer_putuint16(&rdlen,
  436. (isc_uint16_t)(target->used -
  437. rdlen.used - 2));
  438. added++;
  439. }
  440. if (shuffle) {
  441. i++;
  442. if (i == count)
  443. result = ISC_R_NOMORE;
  444. else
  445. result = ISC_R_SUCCESS;
  446. } else {
  447. result = dns_rdataset_next(rdataset);
  448. }
  449. } while (result == ISC_R_SUCCESS);
  450. if (result != ISC_R_NOMORE)
  451. goto rollback;
  452. *countp += count;
  453. result = ISC_R_SUCCESS;
  454. goto cleanup;
  455. rollback:
  456. if (partial && result == ISC_R_NOSPACE) {
  457. INSIST(rrbuffer.used < 65536);
  458. dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used);
  459. *countp += added;
  460. *target = rrbuffer;
  461. goto cleanup;
  462. }
  463. INSIST(savedbuffer.used < 65536);
  464. dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
  465. *countp = 0;
  466. *target = savedbuffer;
  467. cleanup:
  468. if (sorted != NULL && sorted != sorted_fixed)
  469. isc_mem_put(cctx->mctx, sorted, count * sizeof(*sorted));
  470. if (shuffled != NULL && shuffled != shuffled_fixed)
  471. isc_mem_put(cctx->mctx, shuffled, count * sizeof(*shuffled));
  472. return (result);
  473. }
  474. isc_result_t
  475. dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
  476. const dns_name_t *owner_name,
  477. dns_compress_t *cctx,
  478. isc_buffer_t *target,
  479. dns_rdatasetorderfunc_t order,
  480. const void *order_arg,
  481. unsigned int options,
  482. unsigned int *countp)
  483. {
  484. return (towiresorted(rdataset, owner_name, cctx, target,
  485. order, order_arg, ISC_FALSE, options,
  486. countp, NULL));
  487. }
  488. isc_result_t
  489. dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
  490. const dns_name_t *owner_name,
  491. dns_compress_t *cctx,
  492. isc_buffer_t *target,
  493. dns_rdatasetorderfunc_t order,
  494. const void *order_arg,
  495. unsigned int options,
  496. unsigned int *countp,
  497. void **state)
  498. {
  499. REQUIRE(state == NULL); /* XXX remove when implemented */
  500. return (towiresorted(rdataset, owner_name, cctx, target,
  501. order, order_arg, ISC_TRUE, options,
  502. countp, state));
  503. }
  504. isc_result_t
  505. dns_rdataset_towire(dns_rdataset_t *rdataset,
  506. dns_name_t *owner_name,
  507. dns_compress_t *cctx,
  508. isc_buffer_t *target,
  509. unsigned int options,
  510. unsigned int *countp)
  511. {
  512. return (towiresorted(rdataset, owner_name, cctx, target,
  513. NULL, NULL, ISC_FALSE, options, countp, NULL));
  514. }
  515. isc_result_t
  516. dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
  517. dns_additionaldatafunc_t add, void *arg)
  518. {
  519. dns_rdata_t rdata = DNS_RDATA_INIT;
  520. isc_result_t result;
  521. /*
  522. * For each rdata in rdataset, call 'add' for each name and type in the
  523. * rdata which is subject to additional section processing.
  524. */
  525. REQUIRE(DNS_RDATASET_VALID(rdataset));
  526. REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
  527. result = dns_rdataset_first(rdataset);
  528. if (result != ISC_R_SUCCESS)
  529. return (result);
  530. do {
  531. dns_rdataset_current(rdataset, &rdata);
  532. result = dns_rdata_additionaldata(&rdata, add, arg);
  533. if (result == ISC_R_SUCCESS)
  534. result = dns_rdataset_next(rdataset);
  535. dns_rdata_reset(&rdata);
  536. } while (result == ISC_R_SUCCESS);
  537. if (result != ISC_R_NOMORE)
  538. return (result);
  539. return (ISC_R_SUCCESS);
  540. }
  541. isc_result_t
  542. dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
  543. REQUIRE(DNS_RDATASET_VALID(rdataset));
  544. REQUIRE(rdataset->methods != NULL);
  545. if (rdataset->methods->addnoqname == NULL)
  546. return (ISC_R_NOTIMPLEMENTED);
  547. return((rdataset->methods->addnoqname)(rdataset, name));
  548. }
  549. isc_result_t
  550. dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
  551. dns_rdataset_t *neg, dns_rdataset_t *negsig)
  552. {
  553. REQUIRE(DNS_RDATASET_VALID(rdataset));
  554. REQUIRE(rdataset->methods != NULL);
  555. if (rdataset->methods->getnoqname == NULL)
  556. return (ISC_R_NOTIMPLEMENTED);
  557. return((rdataset->methods->getnoqname)(rdataset, name, neg, negsig));
  558. }
  559. isc_result_t
  560. dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
  561. REQUIRE(DNS_RDATASET_VALID(rdataset));
  562. REQUIRE(rdataset->methods != NULL);
  563. if (rdataset->methods->addclosest == NULL)
  564. return (ISC_R_NOTIMPLEMENTED);
  565. return((rdataset->methods->addclosest)(rdataset, name));
  566. }
  567. isc_result_t
  568. dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
  569. dns_rdataset_t *neg, dns_rdataset_t *negsig)
  570. {
  571. REQUIRE(DNS_RDATASET_VALID(rdataset));
  572. REQUIRE(rdataset->methods != NULL);
  573. if (rdataset->methods->getclosest == NULL)
  574. return (ISC_R_NOTIMPLEMENTED);
  575. return((rdataset->methods->getclosest)(rdataset, name, neg, negsig));
  576. }
  577. /*
  578. * Additional cache stuff
  579. */
  580. isc_result_t
  581. dns_rdataset_getadditional(dns_rdataset_t *rdataset,
  582. dns_rdatasetadditional_t type,
  583. dns_rdatatype_t qtype,
  584. dns_acache_t *acache,
  585. dns_zone_t **zonep,
  586. dns_db_t **dbp,
  587. dns_dbversion_t **versionp,
  588. dns_dbnode_t **nodep,
  589. dns_name_t *fname,
  590. dns_message_t *msg,
  591. isc_stdtime_t now)
  592. {
  593. REQUIRE(DNS_RDATASET_VALID(rdataset));
  594. REQUIRE(rdataset->methods != NULL);
  595. REQUIRE(zonep == NULL || *zonep == NULL);
  596. REQUIRE(dbp != NULL && *dbp == NULL);
  597. REQUIRE(versionp != NULL && *versionp == NULL);
  598. REQUIRE(nodep != NULL && *nodep == NULL);
  599. REQUIRE(fname != NULL);
  600. REQUIRE(msg != NULL);
  601. if (acache != NULL && rdataset->methods->getadditional != NULL) {
  602. return ((rdataset->methods->getadditional)(rdataset, type,
  603. qtype, acache,
  604. zonep, dbp,
  605. versionp, nodep,
  606. fname, msg, now));
  607. }
  608. return (ISC_R_FAILURE);
  609. }
  610. isc_result_t
  611. dns_rdataset_setadditional(dns_rdataset_t *rdataset,
  612. dns_rdatasetadditional_t type,
  613. dns_rdatatype_t qtype,
  614. dns_acache_t *acache,
  615. dns_zone_t *zone,
  616. dns_db_t *db,
  617. dns_dbversion_t *version,
  618. dns_dbnode_t *node,
  619. dns_name_t *fname)
  620. {
  621. REQUIRE(DNS_RDATASET_VALID(rdataset));
  622. REQUIRE(rdataset->methods != NULL);
  623. if (acache != NULL && rdataset->methods->setadditional != NULL) {
  624. return ((rdataset->methods->setadditional)(rdataset, type,
  625. qtype, acache, zone,
  626. db, version,
  627. node, fname));
  628. }
  629. return (ISC_R_FAILURE);
  630. }
  631. isc_result_t
  632. dns_rdataset_putadditional(dns_acache_t *acache,
  633. dns_rdataset_t *rdataset,
  634. dns_rdatasetadditional_t type,
  635. dns_rdatatype_t qtype)
  636. {
  637. REQUIRE(DNS_RDATASET_VALID(rdataset));
  638. REQUIRE(rdataset->methods != NULL);
  639. if (acache != NULL && rdataset->methods->putadditional != NULL) {
  640. return ((rdataset->methods->putadditional)(acache, rdataset,
  641. type, qtype));
  642. }
  643. return (ISC_R_FAILURE);
  644. }
  645. void
  646. dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
  647. REQUIRE(DNS_RDATASET_VALID(rdataset));
  648. REQUIRE(rdataset->methods != NULL);
  649. if (rdataset->methods->settrust != NULL)
  650. (rdataset->methods->settrust)(rdataset, trust);
  651. else
  652. rdataset->trust = trust;
  653. }
  654. void
  655. dns_rdataset_expire(dns_rdataset_t *rdataset) {
  656. REQUIRE(DNS_RDATASET_VALID(rdataset));
  657. REQUIRE(rdataset->methods != NULL);
  658. if (rdataset->methods->expire != NULL)
  659. (rdataset->methods->expire)(rdataset);
  660. }