[BACK]Return to rdatalist.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mpl / bind / dist / lib / dns

Annotation of src/external/mpl/bind/dist/lib/dns/rdatalist.c, Revision 1.1.1.1

1.1       christos    1: /*     $NetBSD$        */
                      2:
                      3: /*
                      4:  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
                      5:  *
                      6:  * This Source Code Form is subject to the terms of the Mozilla Public
                      7:  * License, v. 2.0. If a copy of the MPL was not distributed with this
                      8:  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
                      9:  *
                     10:  * See the COPYRIGHT file distributed with this work for additional
                     11:  * information regarding copyright ownership.
                     12:  */
                     13:
                     14:
                     15: /*! \file */
                     16:
                     17: #include <config.h>
                     18:
                     19: #include <stddef.h>
                     20: #include <string.h>
                     21:
                     22: #include <isc/util.h>
                     23:
                     24: #include <dns/name.h>
                     25: #include <dns/nsec3.h>
                     26: #include <dns/rdata.h>
                     27: #include <dns/rdatalist.h>
                     28: #include <dns/rdataset.h>
                     29:
                     30: #include "rdatalist_p.h"
                     31:
                     32: static dns_rdatasetmethods_t methods = {
                     33:        isc__rdatalist_disassociate,
                     34:        isc__rdatalist_first,
                     35:        isc__rdatalist_next,
                     36:        isc__rdatalist_current,
                     37:        isc__rdatalist_clone,
                     38:        isc__rdatalist_count,
                     39:        isc__rdatalist_addnoqname,
                     40:        isc__rdatalist_getnoqname,
                     41:        isc__rdatalist_addclosest,
                     42:        isc__rdatalist_getclosest,
                     43:        NULL, /* settrust */
                     44:        NULL, /* expire */
                     45:        NULL, /* clearprefetch */
                     46:        isc__rdatalist_setownercase,
                     47:        isc__rdatalist_getownercase,
                     48:        NULL  /* addglue */
                     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, const 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 = rdataset->rdclass;
                    246:        dns_rdataset_t *tneg = NULL;
                    247:        dns_rdataset_t *tnegsig = NULL;
                    248:        const dns_name_t *noqname = rdataset->private6;
                    249:
                    250:        REQUIRE(rdataset != NULL);
                    251:        REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0);
                    252:
                    253:        (void)dns_name_dynamic(noqname);        /* Sanity Check. */
                    254:
                    255:        for (rdataset = ISC_LIST_HEAD(noqname->list);
                    256:             rdataset != NULL;
                    257:             rdataset = ISC_LIST_NEXT(rdataset, link))
                    258:        {
                    259:                if (rdataset->rdclass != rdclass)
                    260:                        continue;
                    261:                if (rdataset->type == dns_rdatatype_nsec ||
                    262:                    rdataset->type == dns_rdatatype_nsec3)
                    263:                        tneg = rdataset;
                    264:        }
                    265:        if (tneg == NULL)
                    266:                return (ISC_R_NOTFOUND);
                    267:
                    268:        for (rdataset = ISC_LIST_HEAD(noqname->list);
                    269:             rdataset != NULL;
                    270:             rdataset = ISC_LIST_NEXT(rdataset, link))
                    271:        {
                    272:                if (rdataset->type == dns_rdatatype_rrsig &&
                    273:                    rdataset->covers == tneg->type)
                    274:                        tnegsig = rdataset;
                    275:        }
                    276:        if (tnegsig == NULL)
                    277:                return (ISC_R_NOTFOUND);
                    278:
                    279:        dns_name_clone(noqname, name);
                    280:        dns_rdataset_clone(tneg, neg);
                    281:        dns_rdataset_clone(tnegsig, negsig);
                    282:        return (ISC_R_SUCCESS);
                    283: }
                    284:
                    285: isc_result_t
                    286: isc__rdatalist_addclosest(dns_rdataset_t *rdataset, const dns_name_t *name) {
                    287:        dns_rdataset_t *neg = NULL;
                    288:        dns_rdataset_t *negsig = NULL;
                    289:        dns_rdataset_t *rdset;
                    290:        dns_ttl_t ttl;
                    291:
                    292:        REQUIRE(rdataset != NULL);
                    293:
                    294:        for (rdset = ISC_LIST_HEAD(name->list);
                    295:             rdset != NULL;
                    296:             rdset = ISC_LIST_NEXT(rdset, link))
                    297:        {
                    298:                if (rdset->rdclass != rdataset->rdclass)
                    299:                        continue;
                    300:                if (rdset->type == dns_rdatatype_nsec ||
                    301:                    rdset->type == dns_rdatatype_nsec3)
                    302:                        neg = rdset;
                    303:        }
                    304:        if (neg == NULL)
                    305:                return (ISC_R_NOTFOUND);
                    306:
                    307:        for (rdset = ISC_LIST_HEAD(name->list);
                    308:             rdset != NULL;
                    309:             rdset = ISC_LIST_NEXT(rdset, link))
                    310:        {
                    311:                if (rdset->type == dns_rdatatype_rrsig &&
                    312:                    rdset->covers == neg->type)
                    313:                        negsig = rdset;
                    314:        }
                    315:
                    316:        if (negsig == NULL)
                    317:                return (ISC_R_NOTFOUND);
                    318:        /*
                    319:         * Minimise ttl.
                    320:         */
                    321:        ttl = rdataset->ttl;
                    322:        if (neg->ttl < ttl)
                    323:                ttl = neg->ttl;
                    324:        if (negsig->ttl < ttl)
                    325:                ttl = negsig->ttl;
                    326:        rdataset->ttl = neg->ttl = negsig->ttl = ttl;
                    327:        rdataset->attributes |= DNS_RDATASETATTR_CLOSEST;
                    328:        rdataset->private7 = name;
                    329:        return (ISC_R_SUCCESS);
                    330: }
                    331:
                    332: isc_result_t
                    333: isc__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
                    334:                          dns_rdataset_t *neg, dns_rdataset_t *negsig)
                    335: {
                    336:        dns_rdataclass_t rdclass = rdataset->rdclass;
                    337:        dns_rdataset_t *tneg = NULL;
                    338:        dns_rdataset_t *tnegsig = NULL;
                    339:        const dns_name_t *closest = rdataset->private7;
                    340:
                    341:        REQUIRE(rdataset != NULL);
                    342:        REQUIRE((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0);
                    343:
                    344:        (void)dns_name_dynamic(closest);        /* Sanity Check. */
                    345:
                    346:        for (rdataset = ISC_LIST_HEAD(closest->list);
                    347:             rdataset != NULL;
                    348:             rdataset = ISC_LIST_NEXT(rdataset, link))
                    349:        {
                    350:                if (rdataset->rdclass != rdclass)
                    351:                        continue;
                    352:                if (rdataset->type == dns_rdatatype_nsec ||
                    353:                    rdataset->type == dns_rdatatype_nsec3)
                    354:                        tneg = rdataset;
                    355:        }
                    356:        if (tneg == NULL)
                    357:                return (ISC_R_NOTFOUND);
                    358:
                    359:        for (rdataset = ISC_LIST_HEAD(closest->list);
                    360:             rdataset != NULL;
                    361:             rdataset = ISC_LIST_NEXT(rdataset, link))
                    362:        {
                    363:                if (rdataset->type == dns_rdatatype_rrsig &&
                    364:                    rdataset->covers == tneg->type)
                    365:                        tnegsig = rdataset;
                    366:        }
                    367:        if (tnegsig == NULL)
                    368:                return (ISC_R_NOTFOUND);
                    369:
                    370:        dns_name_clone(closest, name);
                    371:        dns_rdataset_clone(tneg, neg);
                    372:        dns_rdataset_clone(tnegsig, negsig);
                    373:        return (ISC_R_SUCCESS);
                    374: }
                    375:
                    376: void
                    377: isc__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
                    378:        dns_rdatalist_t *rdatalist;
                    379:        unsigned int i;
                    380:
                    381:        /*
                    382:         * We do not need to worry about label lengths as they are all
                    383:         * less than or equal to 63.
                    384:         */
                    385:        rdatalist = rdataset->private1;
                    386:        memset(rdatalist->upper, 0, sizeof(rdatalist->upper));
                    387:        for (i = 1; i < name->length; i++)
                    388:                if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a)
                    389:                        rdatalist->upper[i/8] |= 1 << (i%8);
                    390:        /*
                    391:         * Record that upper has been set.
                    392:         */
                    393:        rdatalist->upper[0] |= 0x01;
                    394: }
                    395:
                    396: void
                    397: isc__rdatalist_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
                    398:        dns_rdatalist_t *rdatalist;
                    399:        unsigned int i;
                    400:
                    401:        rdatalist = rdataset->private1;
                    402:        if ((rdatalist->upper[0] & 0x01) == 0)
                    403:                return;
                    404:        for (i = 0; i < name->length; i++) {
                    405:                /*
                    406:                 * Set the case bit if it does not match the recorded bit.
                    407:                 */
                    408:                if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
                    409:                    (rdatalist->upper[i/8] & (1 << (i%8))) != 0)
                    410:                        name->ndata[i] &= ~0x20; /* clear the lower case bit */
                    411:                else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
                    412:                    (rdatalist->upper[i/8] & (1 << (i%8))) == 0)
                    413:                        name->ndata[i] |= 0x20; /* set the lower case bit */
                    414:        }
                    415: }

CVSweb <webmaster@jp.NetBSD.org>