/contrib/bind9/lib/dns/order.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 167 lines · 122 code · 26 blank · 19 comment · 32 complexity · 1e616a7c3060b2ad4cc2678b8bdc4894 MD5 · raw file

  1. /*
  2. * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2002 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: order.c,v 1.10 2007/06/19 23:47:16 tbox Exp $ */
  18. /*! \file */
  19. #include <config.h>
  20. #include <isc/magic.h>
  21. #include <isc/mem.h>
  22. #include <isc/types.h>
  23. #include <isc/util.h>
  24. #include <isc/refcount.h>
  25. #include <dns/fixedname.h>
  26. #include <dns/name.h>
  27. #include <dns/order.h>
  28. #include <dns/rdataset.h>
  29. #include <dns/types.h>
  30. typedef struct dns_order_ent dns_order_ent_t;
  31. struct dns_order_ent {
  32. dns_fixedname_t name;
  33. dns_rdataclass_t rdclass;
  34. dns_rdatatype_t rdtype;
  35. unsigned int mode;
  36. ISC_LINK(dns_order_ent_t) link;
  37. };
  38. struct dns_order {
  39. unsigned int magic;
  40. isc_refcount_t references;
  41. ISC_LIST(dns_order_ent_t) ents;
  42. isc_mem_t *mctx;
  43. };
  44. #define DNS_ORDER_MAGIC ISC_MAGIC('O','r','d','r')
  45. #define DNS_ORDER_VALID(order) ISC_MAGIC_VALID(order, DNS_ORDER_MAGIC)
  46. isc_result_t
  47. dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) {
  48. dns_order_t *order;
  49. isc_result_t result;
  50. REQUIRE(orderp != NULL && *orderp == NULL);
  51. order = isc_mem_get(mctx, sizeof(*order));
  52. if (order == NULL)
  53. return (ISC_R_NOMEMORY);
  54. ISC_LIST_INIT(order->ents);
  55. /* Implicit attach. */
  56. result = isc_refcount_init(&order->references, 1);
  57. if (result != ISC_R_SUCCESS) {
  58. isc_mem_put(mctx, order, sizeof(*order));
  59. return (result);
  60. }
  61. order->mctx = NULL;
  62. isc_mem_attach(mctx, &order->mctx);
  63. order->magic = DNS_ORDER_MAGIC;
  64. *orderp = order;
  65. return (ISC_R_SUCCESS);
  66. }
  67. isc_result_t
  68. dns_order_add(dns_order_t *order, dns_name_t *name,
  69. dns_rdatatype_t rdtype, dns_rdataclass_t rdclass,
  70. unsigned int mode)
  71. {
  72. dns_order_ent_t *ent;
  73. REQUIRE(DNS_ORDER_VALID(order));
  74. REQUIRE(mode == DNS_RDATASETATTR_RANDOMIZE ||
  75. mode == DNS_RDATASETATTR_FIXEDORDER ||
  76. mode == 0 /* DNS_RDATASETATTR_CYCLIC */ );
  77. ent = isc_mem_get(order->mctx, sizeof(*ent));
  78. if (ent == NULL)
  79. return (ISC_R_NOMEMORY);
  80. dns_fixedname_init(&ent->name);
  81. RUNTIME_CHECK(dns_name_copy(name, dns_fixedname_name(&ent->name), NULL)
  82. == ISC_R_SUCCESS);
  83. ent->rdtype = rdtype;
  84. ent->rdclass = rdclass;
  85. ent->mode = mode;
  86. ISC_LINK_INIT(ent, link);
  87. ISC_LIST_INITANDAPPEND(order->ents, ent, link);
  88. return (ISC_R_SUCCESS);
  89. }
  90. static inline isc_boolean_t
  91. match(dns_name_t *name1, dns_name_t *name2) {
  92. if (dns_name_iswildcard(name2))
  93. return(dns_name_matcheswildcard(name1, name2));
  94. return (dns_name_equal(name1, name2));
  95. }
  96. unsigned int
  97. dns_order_find(dns_order_t *order, dns_name_t *name,
  98. dns_rdatatype_t rdtype, dns_rdataclass_t rdclass)
  99. {
  100. dns_order_ent_t *ent;
  101. REQUIRE(DNS_ORDER_VALID(order));
  102. for (ent = ISC_LIST_HEAD(order->ents);
  103. ent != NULL;
  104. ent = ISC_LIST_NEXT(ent, link)) {
  105. if (ent->rdtype != rdtype && ent->rdtype != dns_rdatatype_any)
  106. continue;
  107. if (ent->rdclass != rdclass &&
  108. ent->rdclass != dns_rdataclass_any)
  109. continue;
  110. if (match(name, dns_fixedname_name(&ent->name)))
  111. return (ent->mode);
  112. }
  113. return (0);
  114. }
  115. void
  116. dns_order_attach(dns_order_t *source, dns_order_t **target) {
  117. REQUIRE(DNS_ORDER_VALID(source));
  118. REQUIRE(target != NULL && *target == NULL);
  119. isc_refcount_increment(&source->references, NULL);
  120. *target = source;
  121. }
  122. void
  123. dns_order_detach(dns_order_t **orderp) {
  124. dns_order_t *order;
  125. dns_order_ent_t *ent;
  126. unsigned int references;
  127. REQUIRE(orderp != NULL);
  128. order = *orderp;
  129. REQUIRE(DNS_ORDER_VALID(order));
  130. isc_refcount_decrement(&order->references, &references);
  131. *orderp = NULL;
  132. if (references != 0)
  133. return;
  134. order->magic = 0;
  135. while ((ent = ISC_LIST_HEAD(order->ents)) != NULL) {
  136. ISC_LIST_UNLINK(order->ents, ent, link);
  137. isc_mem_put(order->mctx, ent, sizeof(*ent));
  138. }
  139. isc_refcount_destroy(&order->references);
  140. isc_mem_putanddetach(&order->mctx, order, sizeof(*order));
  141. }