"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.17.5/lib/dns/rdatalist.c" (4 Sep 2020, 9885 Bytes) of package /linux/misc/dns/bind9/9.17.5/bind-9.17.5.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rdatalist.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 /*! \file */
   13 
   14 #include <stddef.h>
   15 #include <string.h>
   16 
   17 #include <isc/util.h>
   18 
   19 #include <dns/name.h>
   20 #include <dns/nsec3.h>
   21 #include <dns/rdata.h>
   22 #include <dns/rdatalist.h>
   23 #include <dns/rdataset.h>
   24 
   25 #include "rdatalist_p.h"
   26 
   27 static dns_rdatasetmethods_t methods = {
   28     isc__rdatalist_disassociate,
   29     isc__rdatalist_first,
   30     isc__rdatalist_next,
   31     isc__rdatalist_current,
   32     isc__rdatalist_clone,
   33     isc__rdatalist_count,
   34     isc__rdatalist_addnoqname,
   35     isc__rdatalist_getnoqname,
   36     isc__rdatalist_addclosest,
   37     isc__rdatalist_getclosest,
   38     NULL, /* settrust */
   39     NULL, /* expire */
   40     NULL, /* clearprefetch */
   41     isc__rdatalist_setownercase,
   42     isc__rdatalist_getownercase,
   43     NULL /* addglue */
   44 };
   45 
   46 void
   47 dns_rdatalist_init(dns_rdatalist_t *rdatalist) {
   48     REQUIRE(rdatalist != NULL);
   49 
   50     /*
   51      * Initialize rdatalist.
   52      */
   53 
   54     rdatalist->rdclass = 0;
   55     rdatalist->type = 0;
   56     rdatalist->covers = 0;
   57     rdatalist->ttl = 0;
   58     ISC_LIST_INIT(rdatalist->rdata);
   59     ISC_LINK_INIT(rdatalist, link);
   60     memset(rdatalist->upper, 0xeb, sizeof(rdatalist->upper));
   61     /*
   62      * Clear upper set bit.
   63      */
   64     rdatalist->upper[0] &= ~0x01;
   65 }
   66 
   67 isc_result_t
   68 dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist, dns_rdataset_t *rdataset) {
   69     /*
   70      * Make 'rdataset' refer to the rdata in 'rdatalist'.
   71      */
   72 
   73     REQUIRE(rdatalist != NULL);
   74     REQUIRE(DNS_RDATASET_VALID(rdataset));
   75     REQUIRE(!dns_rdataset_isassociated(rdataset));
   76 
   77     /* Check if dns_rdatalist_init has was called. */
   78     REQUIRE(rdatalist->upper[0] == 0xea);
   79 
   80     rdataset->methods = &methods;
   81     rdataset->rdclass = rdatalist->rdclass;
   82     rdataset->type = rdatalist->type;
   83     rdataset->covers = rdatalist->covers;
   84     rdataset->ttl = rdatalist->ttl;
   85     rdataset->trust = 0;
   86     rdataset->private1 = rdatalist;
   87     rdataset->private2 = NULL;
   88     rdataset->private3 = NULL;
   89     rdataset->privateuint4 = 0;
   90     rdataset->private5 = NULL;
   91 
   92     return (ISC_R_SUCCESS);
   93 }
   94 
   95 isc_result_t
   96 dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset,
   97                dns_rdatalist_t **rdatalist) {
   98     REQUIRE(rdatalist != NULL && rdataset != NULL);
   99     *rdatalist = rdataset->private1;
  100 
  101     return (ISC_R_SUCCESS);
  102 }
  103 
  104 void
  105 isc__rdatalist_disassociate(dns_rdataset_t *rdataset) {
  106     UNUSED(rdataset);
  107 }
  108 
  109 isc_result_t
  110 isc__rdatalist_first(dns_rdataset_t *rdataset) {
  111     dns_rdatalist_t *rdatalist;
  112 
  113     rdatalist = rdataset->private1;
  114     rdataset->private2 = ISC_LIST_HEAD(rdatalist->rdata);
  115 
  116     if (rdataset->private2 == NULL) {
  117         return (ISC_R_NOMORE);
  118     }
  119 
  120     return (ISC_R_SUCCESS);
  121 }
  122 
  123 isc_result_t
  124 isc__rdatalist_next(dns_rdataset_t *rdataset) {
  125     dns_rdata_t *rdata;
  126 
  127     REQUIRE(rdataset != NULL);
  128 
  129     rdata = rdataset->private2;
  130     if (rdata == NULL) {
  131         return (ISC_R_NOMORE);
  132     }
  133 
  134     rdataset->private2 = ISC_LIST_NEXT(rdata, link);
  135 
  136     if (rdataset->private2 == NULL) {
  137         return (ISC_R_NOMORE);
  138     }
  139 
  140     return (ISC_R_SUCCESS);
  141 }
  142 
  143 void
  144 isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
  145     dns_rdata_t *list_rdata;
  146 
  147     REQUIRE(rdataset != NULL);
  148 
  149     list_rdata = rdataset->private2;
  150     INSIST(list_rdata != NULL);
  151 
  152     dns_rdata_clone(list_rdata, rdata);
  153 }
  154 
  155 void
  156 isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
  157     REQUIRE(source != NULL);
  158     REQUIRE(target != NULL);
  159 
  160     *target = *source;
  161 
  162     /*
  163      * Reset iterator state.
  164      */
  165     target->private2 = NULL;
  166 }
  167 
  168 unsigned int
  169 isc__rdatalist_count(dns_rdataset_t *rdataset) {
  170     dns_rdatalist_t *rdatalist;
  171     dns_rdata_t *rdata;
  172     unsigned int count;
  173 
  174     REQUIRE(rdataset != NULL);
  175 
  176     rdatalist = rdataset->private1;
  177 
  178     count = 0;
  179     for (rdata = ISC_LIST_HEAD(rdatalist->rdata); rdata != NULL;
  180          rdata = ISC_LIST_NEXT(rdata, link))
  181     {
  182         count++;
  183     }
  184 
  185     return (count);
  186 }
  187 
  188 isc_result_t
  189 isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, const dns_name_t *name) {
  190     dns_rdataset_t *neg = NULL;
  191     dns_rdataset_t *negsig = NULL;
  192     dns_rdataset_t *rdset;
  193     dns_ttl_t ttl;
  194 
  195     REQUIRE(rdataset != NULL);
  196 
  197     for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL;
  198          rdset = ISC_LIST_NEXT(rdset, link))
  199     {
  200         if (rdset->rdclass != rdataset->rdclass) {
  201             continue;
  202         }
  203         if (rdset->type == dns_rdatatype_nsec ||
  204             rdset->type == dns_rdatatype_nsec3) {
  205             neg = rdset;
  206         }
  207     }
  208     if (neg == NULL) {
  209         return (ISC_R_NOTFOUND);
  210     }
  211 
  212     for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL;
  213          rdset = ISC_LIST_NEXT(rdset, link))
  214     {
  215         if (rdset->type == dns_rdatatype_rrsig &&
  216             rdset->covers == neg->type) {
  217             negsig = rdset;
  218         }
  219     }
  220 
  221     if (negsig == NULL) {
  222         return (ISC_R_NOTFOUND);
  223     }
  224     /*
  225      * Minimise ttl.
  226      */
  227     ttl = rdataset->ttl;
  228     if (neg->ttl < ttl) {
  229         ttl = neg->ttl;
  230     }
  231     if (negsig->ttl < ttl) {
  232         ttl = negsig->ttl;
  233     }
  234     rdataset->ttl = neg->ttl = negsig->ttl = ttl;
  235     rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
  236     rdataset->private6 = name;
  237     return (ISC_R_SUCCESS);
  238 }
  239 
  240 isc_result_t
  241 isc__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
  242               dns_rdataset_t *neg, dns_rdataset_t *negsig) {
  243     dns_rdataclass_t rdclass;
  244     dns_rdataset_t *tneg = NULL;
  245     dns_rdataset_t *tnegsig = NULL;
  246     const dns_name_t *noqname;
  247 
  248     REQUIRE(rdataset != NULL);
  249     REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0);
  250 
  251     rdclass = rdataset->rdclass;
  252     noqname = rdataset->private6;
  253 
  254     (void)dns_name_dynamic(noqname); /* Sanity Check. */
  255 
  256     for (rdataset = ISC_LIST_HEAD(noqname->list); rdataset != NULL;
  257          rdataset = ISC_LIST_NEXT(rdataset, link))
  258     {
  259         if (rdataset->rdclass != rdclass) {
  260             continue;
  261         }
  262         if (rdataset->type == dns_rdatatype_nsec ||
  263             rdataset->type == dns_rdatatype_nsec3)
  264         {
  265             tneg = rdataset;
  266         }
  267     }
  268     if (tneg == NULL) {
  269         return (ISC_R_NOTFOUND);
  270     }
  271 
  272     for (rdataset = ISC_LIST_HEAD(noqname->list); rdataset != NULL;
  273          rdataset = ISC_LIST_NEXT(rdataset, link))
  274     {
  275         if (rdataset->type == dns_rdatatype_rrsig &&
  276             rdataset->covers == tneg->type) {
  277             tnegsig = rdataset;
  278         }
  279     }
  280     if (tnegsig == NULL) {
  281         return (ISC_R_NOTFOUND);
  282     }
  283 
  284     dns_name_clone(noqname, name);
  285     dns_rdataset_clone(tneg, neg);
  286     dns_rdataset_clone(tnegsig, negsig);
  287     return (ISC_R_SUCCESS);
  288 }
  289 
  290 isc_result_t
  291 isc__rdatalist_addclosest(dns_rdataset_t *rdataset, const dns_name_t *name) {
  292     dns_rdataset_t *neg = NULL;
  293     dns_rdataset_t *negsig = NULL;
  294     dns_rdataset_t *rdset;
  295     dns_ttl_t ttl;
  296 
  297     REQUIRE(rdataset != NULL);
  298 
  299     for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL;
  300          rdset = ISC_LIST_NEXT(rdset, link))
  301     {
  302         if (rdset->rdclass != rdataset->rdclass) {
  303             continue;
  304         }
  305         if (rdset->type == dns_rdatatype_nsec ||
  306             rdset->type == dns_rdatatype_nsec3) {
  307             neg = rdset;
  308         }
  309     }
  310     if (neg == NULL) {
  311         return (ISC_R_NOTFOUND);
  312     }
  313 
  314     for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL;
  315          rdset = ISC_LIST_NEXT(rdset, link))
  316     {
  317         if (rdset->type == dns_rdatatype_rrsig &&
  318             rdset->covers == neg->type) {
  319             negsig = rdset;
  320         }
  321     }
  322 
  323     if (negsig == NULL) {
  324         return (ISC_R_NOTFOUND);
  325     }
  326     /*
  327      * Minimise ttl.
  328      */
  329     ttl = rdataset->ttl;
  330     if (neg->ttl < ttl) {
  331         ttl = neg->ttl;
  332     }
  333     if (negsig->ttl < ttl) {
  334         ttl = negsig->ttl;
  335     }
  336     rdataset->ttl = neg->ttl = negsig->ttl = ttl;
  337     rdataset->attributes |= DNS_RDATASETATTR_CLOSEST;
  338     rdataset->private7 = name;
  339     return (ISC_R_SUCCESS);
  340 }
  341 
  342 isc_result_t
  343 isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
  344               dns_rdataset_t *neg, dns_rdataset_t *negsig) {
  345     dns_rdataclass_t rdclass;
  346     dns_rdataset_t *tneg = NULL;
  347     dns_rdataset_t *tnegsig = NULL;
  348     const dns_name_t *closest;
  349 
  350     REQUIRE(rdataset != NULL);
  351     REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0);
  352 
  353     rdclass = rdataset->rdclass;
  354     closest = rdataset->private7;
  355 
  356     (void)dns_name_dynamic(closest); /* Sanity Check. */
  357 
  358     for (rdataset = ISC_LIST_HEAD(closest->list); rdataset != NULL;
  359          rdataset = ISC_LIST_NEXT(rdataset, link))
  360     {
  361         if (rdataset->rdclass != rdclass) {
  362             continue;
  363         }
  364         if (rdataset->type == dns_rdatatype_nsec ||
  365             rdataset->type == dns_rdatatype_nsec3)
  366         {
  367             tneg = rdataset;
  368         }
  369     }
  370     if (tneg == NULL) {
  371         return (ISC_R_NOTFOUND);
  372     }
  373 
  374     for (rdataset = ISC_LIST_HEAD(closest->list); rdataset != NULL;
  375          rdataset = ISC_LIST_NEXT(rdataset, link))
  376     {
  377         if (rdataset->type == dns_rdatatype_rrsig &&
  378             rdataset->covers == tneg->type) {
  379             tnegsig = rdataset;
  380         }
  381     }
  382     if (tnegsig == NULL) {
  383         return (ISC_R_NOTFOUND);
  384     }
  385 
  386     dns_name_clone(closest, name);
  387     dns_rdataset_clone(tneg, neg);
  388     dns_rdataset_clone(tnegsig, negsig);
  389     return (ISC_R_SUCCESS);
  390 }
  391 
  392 void
  393 isc__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
  394     dns_rdatalist_t *rdatalist;
  395     unsigned int i;
  396 
  397     /*
  398      * We do not need to worry about label lengths as they are all
  399      * less than or equal to 63.
  400      */
  401     rdatalist = rdataset->private1;
  402     memset(rdatalist->upper, 0, sizeof(rdatalist->upper));
  403     for (i = 1; i < name->length; i++) {
  404         if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a) {
  405             rdatalist->upper[i / 8] |= 1 << (i % 8);
  406             /*
  407              * Record that upper has been set.
  408              */
  409         }
  410     }
  411     /*
  412      * Record that upper has been set.
  413      */
  414     rdatalist->upper[0] |= 0x01;
  415 }
  416 
  417 void
  418 isc__rdatalist_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
  419     dns_rdatalist_t *rdatalist;
  420     unsigned int i;
  421 
  422     rdatalist = rdataset->private1;
  423     if ((rdatalist->upper[0] & 0x01) == 0) {
  424         return;
  425     }
  426     for (i = 0; i < name->length; i++) {
  427         /*
  428          * Set the case bit if it does not match the recorded bit.
  429          */
  430         if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
  431             (rdatalist->upper[i / 8] & (1 << (i % 8))) != 0)
  432         {
  433             name->ndata[i] &= ~0x20; /* clear the lower case bit */
  434         } else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
  435                (rdatalist->upper[i / 8] & (1 << (i % 8))) == 0)
  436         {
  437             name->ndata[i] |= 0x20; /* set the lower case bit */
  438         }
  439     }
  440 }