lwsearch.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 2000, 2001  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: lwsearch.c,v 1.13 2007/06/19 23:46:59 tbox Exp $ */
00019 
00020 /*! \file */
00021 
00022 #include <config.h>
00023 
00024 #include <isc/magic.h>
00025 #include <isc/mem.h>
00026 #include <isc/mutex.h>
00027 #include <isc/result.h>
00028 #include <isc/types.h>
00029 #include <isc/util.h>
00030 
00031 #include <dns/name.h>
00032 #include <dns/types.h>
00033 
00034 #include <named/lwsearch.h>
00035 #include <named/types.h>
00036 
00037 #define LWSEARCHLIST_MAGIC              ISC_MAGIC('L', 'W', 'S', 'L')
00038 #define VALID_LWSEARCHLIST(l)           ISC_MAGIC_VALID(l, LWSEARCHLIST_MAGIC)
00039 
00040 isc_result_t
00041 ns_lwsearchlist_create(isc_mem_t *mctx, ns_lwsearchlist_t **listp) {
00042         ns_lwsearchlist_t *list;
00043         isc_result_t result;
00044 
00045         REQUIRE(mctx != NULL);
00046         REQUIRE(listp != NULL && *listp == NULL);
00047 
00048         list = isc_mem_get(mctx, sizeof(ns_lwsearchlist_t));
00049         if (list == NULL)
00050                 return (ISC_R_NOMEMORY);
00051         
00052         result = isc_mutex_init(&list->lock);
00053         if (result != ISC_R_SUCCESS) {
00054                 isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t));
00055                 return (result);
00056         }
00057         list->mctx = NULL;
00058         isc_mem_attach(mctx, &list->mctx);
00059         list->refs = 1;
00060         ISC_LIST_INIT(list->names);
00061         list->magic = LWSEARCHLIST_MAGIC;
00062 
00063         *listp = list;
00064         return (ISC_R_SUCCESS);
00065 }
00066 
00067 void
00068 ns_lwsearchlist_attach(ns_lwsearchlist_t *source, ns_lwsearchlist_t **target) {
00069         REQUIRE(VALID_LWSEARCHLIST(source));
00070         REQUIRE(target != NULL && *target == NULL);
00071 
00072         LOCK(&source->lock);
00073         INSIST(source->refs > 0);
00074         source->refs++;
00075         INSIST(source->refs != 0);
00076         UNLOCK(&source->lock);
00077 
00078         *target = source;
00079 }
00080 
00081 void
00082 ns_lwsearchlist_detach(ns_lwsearchlist_t **listp) {
00083         ns_lwsearchlist_t *list;
00084         isc_mem_t *mctx;
00085 
00086         REQUIRE(listp != NULL);
00087         list = *listp;
00088         REQUIRE(VALID_LWSEARCHLIST(list));
00089 
00090         LOCK(&list->lock);
00091         INSIST(list->refs > 0);
00092         list->refs--;
00093         UNLOCK(&list->lock);
00094 
00095         *listp = NULL;
00096         if (list->refs != 0)
00097                 return;
00098 
00099         mctx = list->mctx;
00100         while (!ISC_LIST_EMPTY(list->names)) {
00101                 dns_name_t *name = ISC_LIST_HEAD(list->names);
00102                 ISC_LIST_UNLINK(list->names, name, link);
00103                 dns_name_free(name, list->mctx);
00104                 isc_mem_put(list->mctx, name, sizeof(dns_name_t));
00105         }
00106         list->magic = 0;
00107         isc_mem_put(mctx, list, sizeof(ns_lwsearchlist_t));
00108         isc_mem_detach(&mctx);
00109 }
00110 
00111 isc_result_t
00112 ns_lwsearchlist_append(ns_lwsearchlist_t *list, dns_name_t *name) {
00113         dns_name_t *newname;
00114         isc_result_t result;
00115 
00116         REQUIRE(VALID_LWSEARCHLIST(list));
00117         REQUIRE(name != NULL);
00118 
00119         newname = isc_mem_get(list->mctx, sizeof(dns_name_t));
00120         if (newname == NULL)
00121                 return (ISC_R_NOMEMORY);
00122         dns_name_init(newname, NULL);
00123         result = dns_name_dup(name, list->mctx, newname);
00124         if (result != ISC_R_SUCCESS) {
00125                 isc_mem_put(list->mctx, newname, sizeof(dns_name_t));
00126                 return (result);
00127         }
00128         ISC_LINK_INIT(newname, link);
00129         ISC_LIST_APPEND(list->names, newname, link);
00130         return (ISC_R_SUCCESS);
00131 }
00132 
00133 void
00134 ns_lwsearchctx_init(ns_lwsearchctx_t *sctx, ns_lwsearchlist_t *list,
00135                     dns_name_t *name, unsigned int ndots)
00136 {
00137         INSIST(sctx != NULL);
00138         sctx->relname = name;
00139         sctx->searchname = NULL;
00140         sctx->doneexact = ISC_FALSE;
00141         sctx->exactfirst = ISC_FALSE;
00142         sctx->ndots = ndots;
00143         if (dns_name_isabsolute(name) || list == NULL) {
00144                 sctx->list = NULL;
00145                 return;
00146         }
00147         sctx->list = list;
00148         sctx->searchname = ISC_LIST_HEAD(sctx->list->names);
00149         if (dns_name_countlabels(name) > ndots)
00150                 sctx->exactfirst = ISC_TRUE;
00151 }
00152 
00153 void
00154 ns_lwsearchctx_first(ns_lwsearchctx_t *sctx) {
00155         REQUIRE(sctx != NULL);
00156         UNUSED(sctx);
00157 }
00158 
00159 isc_result_t
00160 ns_lwsearchctx_next(ns_lwsearchctx_t *sctx) {
00161         REQUIRE(sctx != NULL);
00162 
00163         if (sctx->list == NULL)
00164                 return (ISC_R_NOMORE);
00165 
00166         if (sctx->searchname == NULL) {
00167                 INSIST (!sctx->exactfirst || sctx->doneexact);
00168                 if (sctx->exactfirst || sctx->doneexact)
00169                         return (ISC_R_NOMORE);
00170                 sctx->doneexact = ISC_TRUE;
00171         } else {
00172                 if (sctx->exactfirst && !sctx->doneexact)
00173                         sctx->doneexact = ISC_TRUE;
00174                 else {
00175                         sctx->searchname = ISC_LIST_NEXT(sctx->searchname,
00176                                                          link);
00177                         if (sctx->searchname == NULL && sctx->doneexact)
00178                                 return (ISC_R_NOMORE);
00179                 }
00180         }
00181 
00182         return (ISC_R_SUCCESS);
00183 }
00184 
00185 isc_result_t
00186 ns_lwsearchctx_current(ns_lwsearchctx_t *sctx, dns_name_t *absname) {
00187         dns_name_t *tname;
00188         isc_boolean_t useexact = ISC_FALSE;
00189 
00190         REQUIRE(sctx != NULL);
00191 
00192         if (sctx->list == NULL ||
00193             sctx->searchname == NULL ||
00194             (sctx->exactfirst && !sctx->doneexact))
00195                 useexact = ISC_TRUE;
00196 
00197         if (useexact) {
00198                 if (dns_name_isabsolute(sctx->relname))
00199                         tname = NULL;
00200                 else
00201                         tname = dns_rootname;
00202         } else
00203                 tname = sctx->searchname;
00204 
00205         return (dns_name_concatenate(sctx->relname, tname, absname, NULL));
00206 }

Generated on Tue Apr 28 17:40:54 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha