/contrib/bind9/bin/named/lwsearch.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 206 lines · 154 code · 34 blank · 18 comment · 49 complexity · 350d0c4d019cfbadf2a35b29163492eb MD5 · raw file

  1. /*
  2. * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 2000, 2001 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: lwsearch.c,v 1.13 2007/06/19 23:46:59 tbox Exp $ */
  18. /*! \file */
  19. #include <config.h>
  20. #include <isc/magic.h>
  21. #include <isc/mem.h>
  22. #include <isc/mutex.h>
  23. #include <isc/result.h>
  24. #include <isc/types.h>
  25. #include <isc/util.h>
  26. #include <dns/name.h>
  27. #include <dns/types.h>
  28. #include <named/lwsearch.h>
  29. #include <named/types.h>
  30. #define LWSEARCHLIST_MAGIC ISC_MAGIC('L', 'W', 'S', 'L')
  31. #define VALID_LWSEARCHLIST(l) ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC)
  32. isc_result_t
  33. ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp) {
  34. ns_lwsearchlist_t *list;
  35. isc_result_t result;
  36. REQUIRE(mctx != NULL);
  37. REQUIRE(listp != NULL && *listp == NULL);
  38. list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t));
  39. if (list == NULL)
  40. return (ISC_R_NOMEMORY);
  41. result = isc_mutex_init(&list->lock);
  42. if (result != ISC_R_SUCCESS) {
  43. isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t));
  44. return (result);
  45. }
  46. list->mctx = NULL;
  47. isc_mem_attach(mctx, &list->mctx);
  48. list->refs = 1;
  49. ISC_LIST_INIT(list->names);
  50. list->magic = LWSEARCHLIST_MAGIC;
  51. *listp = list;
  52. return (ISC_R_SUCCESS);
  53. }
  54. void
  55. ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target) {
  56. REQUIRE(VALID_LWSEARCHLIST(source));
  57. REQUIRE(target != NULL && *target == NULL);
  58. LOCK(&source->lock);
  59. INSIST(source->refs > 0);
  60. source->refs++;
  61. INSIST(source->refs != 0);
  62. UNLOCK(&source->lock);
  63. *target = source;
  64. }
  65. void
  66. ns_lwsearchlist_detach(ns_lwsearchlist_t **listp) {
  67. ns_lwsearchlist_t *list;
  68. isc_mem_t *mctx;
  69. REQUIRE(listp != NULL);
  70. list = *listp;
  71. REQUIRE(VALID_LWSEARCHLIST(list));
  72. LOCK(&list->lock);
  73. INSIST(list->refs > 0);
  74. list->refs--;
  75. UNLOCK(&list->lock);
  76. *listp = NULL;
  77. if (list->refs != 0)
  78. return;
  79. mctx = list->mctx;
  80. while (!ISC_LIST_EMPTY(list->names)) {
  81. dns_name_t *name = ISC_LIST_HEAD(list->names);
  82. ISC_LIST_UNLINK(list->names, name, link);
  83. dns_name_free(name, list->mctx);
  84. isc_mem_put(list->mctx, name, sizeof(dns_name_t));
  85. }
  86. list->magic = 0;
  87. isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t));
  88. isc_mem_detach(&mctx);
  89. }
  90. isc_result_t
  91. ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) {
  92. dns_name_t *newname;
  93. isc_result_t result;
  94. REQUIRE(VALID_LWSEARCHLIST(list));
  95. REQUIRE(name != NULL);
  96. newname = isc_mem_get(list->mctx, sizeof(dns_name_t));
  97. if (newname == NULL)
  98. return (ISC_R_NOMEMORY);
  99. dns_name_init(newname, NULL);
  100. result = dns_name_dup(name, list->mctx, newname);
  101. if (result != ISC_R_SUCCESS) {
  102. isc_mem_put(list->mctx, newname, sizeof(dns_name_t));
  103. return (result);
  104. }
  105. ISC_LINK_INIT(newname, link);
  106. ISC_LIST_APPEND(list->names, newname, link);
  107. return (ISC_R_SUCCESS);
  108. }
  109. void
  110. ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list,
  111. dns_name_t *name, unsigned int ndots)
  112. {
  113. INSIST(sctx != NULL);
  114. sctx->relname = name;
  115. sctx->searchname = NULL;
  116. sctx->doneexact = ISC_FALSE;
  117. sctx->exactfirst = ISC_FALSE;
  118. sctx->ndots = ndots;
  119. if (dns_name_isabsolute(name) || list == NULL) {
  120. sctx->list = NULL;
  121. return;
  122. }
  123. sctx->list = list;
  124. sctx->searchname = ISC_LIST_HEAD(sctx->list->names);
  125. if (dns_name_countlabels(name) > ndots)
  126. sctx->exactfirst = ISC_TRUE;
  127. }
  128. void
  129. ns_lwsearchctx_first(ns_lwsearchctx_t *sctx) {
  130. REQUIRE(sctx != NULL);
  131. UNUSED(sctx);
  132. }
  133. isc_result_t
  134. ns_lwsearchctx_next(ns_lwsearchctx_t *sctx) {
  135. REQUIRE(sctx != NULL);
  136. if (sctx->list == NULL)
  137. return (ISC_R_NOMORE);
  138. if (sctx->searchname == NULL) {
  139. INSIST (!sctx->exactfirst || sctx->doneexact);
  140. if (sctx->exactfirst || sctx->doneexact)
  141. return (ISC_R_NOMORE);
  142. sctx->doneexact = ISC_TRUE;
  143. } else {
  144. if (sctx->exactfirst && !sctx->doneexact)
  145. sctx->doneexact = ISC_TRUE;
  146. else {
  147. sctx->searchname = ISC_LIST_NEXT(sctx->searchname,
  148. link);
  149. if (sctx->searchname == NULL && sctx->doneexact)
  150. return (ISC_R_NOMORE);
  151. }
  152. }
  153. return (ISC_R_SUCCESS);
  154. }
  155. isc_result_t
  156. ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname) {
  157. dns_name_t *tname;
  158. isc_boolean_t useexact = ISC_FALSE;
  159. REQUIRE(sctx != NULL);
  160. if (sctx->list == NULL ||
  161. sctx->searchname == NULL ||
  162. (sctx->exactfirst && !sctx->doneexact))
  163. useexact = ISC_TRUE;
  164. if (useexact) {
  165. if (dns_name_isabsolute(sctx->relname))
  166. tname = NULL;
  167. else
  168. tname = dns_rootname;
  169. } else
  170. tname = sctx->searchname;
  171. return (dns_name_concatenate(sctx->relname, tname, absname, NULL));
  172. }