2 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: lwsearch.c,v 1.13 2007-06-19 23:46:59 tbox Exp $ */
24 #include <isc/magic.h>
26 #include <isc/mutex.h>
27 #include <isc/result.h>
28 #include <isc/types.h>
32 #include <dns/types.h>
34 #include <named/lwsearch.h>
35 #include <named/types.h>
37 #define LWSEARCHLIST_MAGIC ISC_MAGIC('L', 'W', 'S', 'L')
38 #define VALID_LWSEARCHLIST(l) ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC)
41 ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp) {
42 ns_lwsearchlist_t *list;
45 REQUIRE(mctx != NULL);
46 REQUIRE(listp != NULL && *listp == NULL);
48 list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t));
50 return (ISC_R_NOMEMORY);
52 result = isc_mutex_init(&list->lock);
53 if (result != ISC_R_SUCCESS) {
54 isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t));
58 isc_mem_attach(mctx, &list->mctx);
60 ISC_LIST_INIT(list->names);
61 list->magic = LWSEARCHLIST_MAGIC;
64 return (ISC_R_SUCCESS);
68 ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target) {
69 REQUIRE(VALID_LWSEARCHLIST(source));
70 REQUIRE(target != NULL && *target == NULL);
73 INSIST(source->refs > 0);
75 INSIST(source->refs != 0);
76 UNLOCK(&source->lock);
82 ns_lwsearchlist_detach(ns_lwsearchlist_t **listp) {
83 ns_lwsearchlist_t *list;
86 REQUIRE(listp != NULL);
88 REQUIRE(VALID_LWSEARCHLIST(list));
91 INSIST(list->refs > 0);
100 while (!ISC_LIST_EMPTY(list->names)) {
101 dns_name_t *name = ISC_LIST_HEAD(list->names);
102 ISC_LIST_UNLINK(list->names, name, link);
103 dns_name_free(name, list->mctx);
104 isc_mem_put(list->mctx, name, sizeof(dns_name_t));
107 isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t));
108 isc_mem_detach(&mctx);
112 ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) {
116 REQUIRE(VALID_LWSEARCHLIST(list));
117 REQUIRE(name != NULL);
119 newname = isc_mem_get(list->mctx, sizeof(dns_name_t));
121 return (ISC_R_NOMEMORY);
122 dns_name_init(newname, NULL);
123 result = dns_name_dup(name, list->mctx, newname);
124 if (result != ISC_R_SUCCESS) {
125 isc_mem_put(list->mctx, newname, sizeof(dns_name_t));
128 ISC_LINK_INIT(newname, link);
129 ISC_LIST_APPEND(list->names, newname, link);
130 return (ISC_R_SUCCESS);
134 ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list,
135 dns_name_t *name, unsigned int ndots)
137 INSIST(sctx != NULL);
138 sctx->relname = name;
139 sctx->searchname = NULL;
140 sctx->doneexact = ISC_FALSE;
141 sctx->exactfirst = ISC_FALSE;
143 if (dns_name_isabsolute(name) || list == NULL) {
148 sctx->searchname = ISC_LIST_HEAD(sctx->list->names);
149 if (dns_name_countlabels(name) > ndots)
150 sctx->exactfirst = ISC_TRUE;
154 ns_lwsearchctx_first(ns_lwsearchctx_t *sctx) {
155 REQUIRE(sctx != NULL);
160 ns_lwsearchctx_next(ns_lwsearchctx_t *sctx) {
161 REQUIRE(sctx != NULL);
163 if (sctx->list == NULL)
164 return (ISC_R_NOMORE);
166 if (sctx->searchname == NULL) {
167 INSIST (!sctx->exactfirst || sctx->doneexact);
168 if (sctx->exactfirst || sctx->doneexact)
169 return (ISC_R_NOMORE);
170 sctx->doneexact = ISC_TRUE;
172 if (sctx->exactfirst && !sctx->doneexact)
173 sctx->doneexact = ISC_TRUE;
175 sctx->searchname = ISC_LIST_NEXT(sctx->searchname,
177 if (sctx->searchname == NULL && sctx->doneexact)
178 return (ISC_R_NOMORE);
182 return (ISC_R_SUCCESS);
186 ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname) {
188 isc_boolean_t useexact = ISC_FALSE;
190 REQUIRE(sctx != NULL);
192 if (sctx->list == NULL ||
193 sctx->searchname == NULL ||
194 (sctx->exactfirst && !sctx->doneexact))
198 if (dns_name_isabsolute(sctx->relname))
201 tname = dns_rootname;
203 tname = sctx->searchname;
205 return (dns_name_concatenate(sctx->relname, tname, absname, NULL));