"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/dns/rdatalist.c" (7 Sep 2020, 9646 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


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