[BACK]Return to rdataset.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/rdataset.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: /*! \file */
                     15:
                     16: #include <config.h>
                     17:
                     18: #include <stdlib.h>
                     19:
                     20: #include <isc/buffer.h>
                     21: #include <isc/mem.h>
                     22: #include <isc/random.h>
                     23: #include <isc/serial.h>
                     24: #include <isc/util.h>
                     25:
                     26: #include <dns/compress.h>
                     27: #include <dns/fixedname.h>
                     28: #include <dns/name.h>
                     29: #include <dns/ncache.h>
                     30: #include <dns/rdata.h>
                     31: #include <dns/rdataset.h>
                     32:
                     33: static const char *trustnames[] = {
                     34:        "none",
                     35:        "pending-additional",
                     36:        "pending-answer",
                     37:        "additional",
                     38:        "glue",
                     39:        "answer",
                     40:        "authauthority",
                     41:        "authanswer",
                     42:        "secure",
                     43:        "local" /* aka ultimate */
                     44: };
                     45:
                     46: const char *
                     47: dns_trust_totext(dns_trust_t trust) {
                     48:        if (trust >= sizeof(trustnames)/sizeof(*trustnames))
                     49:                return ("bad");
                     50:        return (trustnames[trust]);
                     51: }
                     52:
                     53: void
                     54: dns_rdataset_init(dns_rdataset_t *rdataset) {
                     55:
                     56:        /*
                     57:         * Make 'rdataset' a valid, disassociated rdataset.
                     58:         */
                     59:
                     60:        REQUIRE(rdataset != NULL);
                     61:
                     62:        rdataset->magic = DNS_RDATASET_MAGIC;
                     63:        rdataset->methods = NULL;
                     64:        ISC_LINK_INIT(rdataset, link);
                     65:        rdataset->rdclass = 0;
                     66:        rdataset->type = 0;
                     67:        rdataset->ttl = 0;
                     68:        rdataset->trust = 0;
                     69:        rdataset->covers = 0;
                     70:        rdataset->attributes = 0;
                     71:        rdataset->count = ISC_UINT32_MAX;
                     72:        rdataset->private1 = NULL;
                     73:        rdataset->private2 = NULL;
                     74:        rdataset->private3 = NULL;
                     75:        rdataset->privateuint4 = 0;
                     76:        rdataset->private5 = NULL;
                     77:        rdataset->private6 = NULL;
                     78:        rdataset->private7 = NULL;
                     79:        rdataset->resign = 0;
                     80: }
                     81:
                     82: void
                     83: dns_rdataset_invalidate(dns_rdataset_t *rdataset) {
                     84:
                     85:        /*
                     86:         * Invalidate 'rdataset'.
                     87:         */
                     88:
                     89:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                     90:        REQUIRE(rdataset->methods == NULL);
                     91:
                     92:        rdataset->magic = 0;
                     93:        ISC_LINK_INIT(rdataset, link);
                     94:        rdataset->rdclass = 0;
                     95:        rdataset->type = 0;
                     96:        rdataset->ttl = 0;
                     97:        rdataset->trust = 0;
                     98:        rdataset->covers = 0;
                     99:        rdataset->attributes = 0;
                    100:        rdataset->count = ISC_UINT32_MAX;
                    101:        rdataset->private1 = NULL;
                    102:        rdataset->private2 = NULL;
                    103:        rdataset->private3 = NULL;
                    104:        rdataset->privateuint4 = 0;
                    105:        rdataset->private5 = NULL;
                    106: }
                    107:
                    108: void
                    109: dns_rdataset_disassociate(dns_rdataset_t *rdataset) {
                    110:
                    111:        /*
                    112:         * Disassociate 'rdataset' from its rdata, allowing it to be reused.
                    113:         */
                    114:
                    115:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    116:        REQUIRE(rdataset->methods != NULL);
                    117:
                    118:        (rdataset->methods->disassociate)(rdataset);
                    119:        rdataset->methods = NULL;
                    120:        ISC_LINK_INIT(rdataset, link);
                    121:        rdataset->rdclass = 0;
                    122:        rdataset->type = 0;
                    123:        rdataset->ttl = 0;
                    124:        rdataset->trust = 0;
                    125:        rdataset->covers = 0;
                    126:        rdataset->attributes = 0;
                    127:        rdataset->count = ISC_UINT32_MAX;
                    128:        rdataset->private1 = NULL;
                    129:        rdataset->private2 = NULL;
                    130:        rdataset->private3 = NULL;
                    131:        rdataset->privateuint4 = 0;
                    132:        rdataset->private5 = NULL;
                    133:        rdataset->private6 = NULL;
                    134: }
                    135:
                    136: isc_boolean_t
                    137: dns_rdataset_isassociated(dns_rdataset_t *rdataset) {
                    138:        /*
                    139:         * Is 'rdataset' associated?
                    140:         */
                    141:
                    142:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    143:
                    144:        if (rdataset->methods != NULL)
                    145:                return (ISC_TRUE);
                    146:
                    147:        return (ISC_FALSE);
                    148: }
                    149:
                    150: static void
                    151: question_disassociate(dns_rdataset_t *rdataset) {
                    152:        UNUSED(rdataset);
                    153: }
                    154:
                    155: static isc_result_t
                    156: question_cursor(dns_rdataset_t *rdataset) {
                    157:        UNUSED(rdataset);
                    158:
                    159:        return (ISC_R_NOMORE);
                    160: }
                    161:
                    162: static void
                    163: question_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
                    164:        /*
                    165:         * This routine should never be called.
                    166:         */
                    167:        UNUSED(rdataset);
                    168:        UNUSED(rdata);
                    169:
                    170:        REQUIRE(0);
                    171: }
                    172:
                    173: static void
                    174: question_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
                    175:        *target = *source;
                    176: }
                    177:
                    178: static unsigned int
                    179: question_count(dns_rdataset_t *rdataset) {
                    180:        /*
                    181:         * This routine should never be called.
                    182:         */
                    183:        UNUSED(rdataset);
                    184:        REQUIRE(0);
                    185:
                    186:        return (0);
                    187: }
                    188:
                    189: static dns_rdatasetmethods_t question_methods = {
                    190:        question_disassociate,
                    191:        question_cursor,
                    192:        question_cursor,
                    193:        question_current,
                    194:        question_clone,
                    195:        question_count,
                    196:        NULL, /* addnoqname */
                    197:        NULL, /* getnoqname */
                    198:        NULL, /* addclosest */
                    199:        NULL, /* getclosest */
                    200:        NULL, /* settrust */
                    201:        NULL, /* expire */
                    202:        NULL, /* clearprefetch */
                    203:        NULL, /* setownercase */
                    204:        NULL, /* getownercase */
                    205:        NULL  /* addglue */
                    206: };
                    207:
                    208: void
                    209: dns_rdataset_makequestion(dns_rdataset_t *rdataset, dns_rdataclass_t rdclass,
                    210:                          dns_rdatatype_t type)
                    211: {
                    212:
                    213:        /*
                    214:         * Make 'rdataset' a valid, associated, question rdataset, with a
                    215:         * question class of 'rdclass' and type 'type'.
                    216:         */
                    217:
                    218:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    219:        REQUIRE(rdataset->methods == NULL);
                    220:
                    221:        rdataset->methods = &question_methods;
                    222:        rdataset->rdclass = rdclass;
                    223:        rdataset->type = type;
                    224:        rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
                    225: }
                    226:
                    227: unsigned int
                    228: dns_rdataset_count(dns_rdataset_t *rdataset) {
                    229:
                    230:        /*
                    231:         * Return the number of records in 'rdataset'.
                    232:         */
                    233:
                    234:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    235:        REQUIRE(rdataset->methods != NULL);
                    236:
                    237:        return ((rdataset->methods->count)(rdataset));
                    238: }
                    239:
                    240: void
                    241: dns_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
                    242:
                    243:        /*
                    244:         * Make 'target' refer to the same rdataset as 'source'.
                    245:         */
                    246:
                    247:        REQUIRE(DNS_RDATASET_VALID(source));
                    248:        REQUIRE(source->methods != NULL);
                    249:        REQUIRE(DNS_RDATASET_VALID(target));
                    250:        REQUIRE(target->methods == NULL);
                    251:
                    252:        (source->methods->clone)(source, target);
                    253: }
                    254:
                    255: isc_result_t
                    256: dns_rdataset_first(dns_rdataset_t *rdataset) {
                    257:
                    258:        /*
                    259:         * Move the rdata cursor to the first rdata in the rdataset (if any).
                    260:         */
                    261:
                    262:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    263:        REQUIRE(rdataset->methods != NULL);
                    264:
                    265:        return ((rdataset->methods->first)(rdataset));
                    266: }
                    267:
                    268: isc_result_t
                    269: dns_rdataset_next(dns_rdataset_t *rdataset) {
                    270:
                    271:        /*
                    272:         * Move the rdata cursor to the next rdata in the rdataset (if any).
                    273:         */
                    274:
                    275:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    276:        REQUIRE(rdataset->methods != NULL);
                    277:
                    278:        return ((rdataset->methods->next)(rdataset));
                    279: }
                    280:
                    281: void
                    282: dns_rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
                    283:
                    284:        /*
                    285:         * Make 'rdata' refer to the current rdata.
                    286:         */
                    287:
                    288:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    289:        REQUIRE(rdataset->methods != NULL);
                    290:
                    291:        (rdataset->methods->current)(rdataset, rdata);
                    292: }
                    293:
                    294: #define MAX_SHUFFLE    32
                    295: #define WANT_FIXED(r)  (((r)->attributes & DNS_RDATASETATTR_FIXEDORDER) != 0)
                    296: #define WANT_RANDOM(r) (((r)->attributes & DNS_RDATASETATTR_RANDOMIZE) != 0)
                    297: #define WANT_CYCLIC(r) (((r)->attributes & DNS_RDATASETATTR_CYCLIC) != 0)
                    298:
                    299: struct towire_sort {
                    300:        int key;
                    301:        dns_rdata_t *rdata;
                    302: };
                    303:
                    304: static int
                    305: towire_compare(const void *av, const void *bv) {
                    306:        const struct towire_sort *a = (const struct towire_sort *) av;
                    307:        const struct towire_sort *b = (const struct towire_sort *) bv;
                    308:        return (a->key - b->key);
                    309: }
                    310:
                    311: static isc_result_t
                    312: towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                    313:             dns_compress_t *cctx, isc_buffer_t *target,
                    314:             dns_rdatasetorderfunc_t order, const void *order_arg,
                    315:             isc_boolean_t partial, unsigned int options,
                    316:             unsigned int *countp, void **state)
                    317: {
                    318:        dns_rdata_t rdata = DNS_RDATA_INIT;
                    319:        isc_region_t r;
                    320:        isc_result_t result;
                    321:        unsigned int i, count = 0, added, choice;
                    322:        isc_buffer_t savedbuffer, rdlen, rrbuffer;
                    323:        unsigned int headlen;
                    324:        isc_boolean_t question = ISC_FALSE;
                    325:        isc_boolean_t shuffle = ISC_FALSE, sort = ISC_FALSE;
                    326:        isc_boolean_t want_random, want_cyclic;
                    327:        dns_rdata_t in_fixed[MAX_SHUFFLE];
                    328:        dns_rdata_t *in = in_fixed;
                    329:        struct towire_sort out_fixed[MAX_SHUFFLE];
                    330:        struct towire_sort *out = out_fixed;
                    331:        dns_fixedname_t fixed;
                    332:        dns_name_t *name;
                    333:        isc_uint16_t offset;
                    334:
                    335:        UNUSED(state);
                    336:
                    337:        /*
                    338:         * Convert 'rdataset' to wire format, compressing names as specified
                    339:         * in cctx, and storing the result in 'target'.
                    340:         */
                    341:
                    342:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    343:        REQUIRE(rdataset->methods != NULL);
                    344:        REQUIRE(countp != NULL);
                    345:        REQUIRE(cctx != NULL && cctx->mctx != NULL);
                    346:
                    347:        want_random = WANT_RANDOM(rdataset);
                    348:        want_cyclic = WANT_CYCLIC(rdataset);
                    349:
                    350:        if ((rdataset->attributes & DNS_RDATASETATTR_QUESTION) != 0) {
                    351:                question = ISC_TRUE;
                    352:                count = 1;
                    353:                result = dns_rdataset_first(rdataset);
                    354:                INSIST(result == ISC_R_NOMORE);
                    355:        } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
                    356:                /*
                    357:                 * This is a negative caching rdataset.
                    358:                 */
                    359:                unsigned int ncache_opts = 0;
                    360:                if ((options & DNS_RDATASETTOWIRE_OMITDNSSEC) != 0)
                    361:                        ncache_opts |= DNS_NCACHETOWIRE_OMITDNSSEC;
                    362:                return (dns_ncache_towire(rdataset, cctx, target, ncache_opts,
                    363:                                          countp));
                    364:        } else {
                    365:                count = (rdataset->methods->count)(rdataset);
                    366:                result = dns_rdataset_first(rdataset);
                    367:                if (result == ISC_R_NOMORE)
                    368:                        return (ISC_R_SUCCESS);
                    369:                if (result != ISC_R_SUCCESS)
                    370:                        return (result);
                    371:        }
                    372:
                    373:        /*
                    374:         * Do we want to sort and/or shuffle this answer?
                    375:         */
                    376:        if (!question && count > 1 && rdataset->type != dns_rdatatype_rrsig) {
                    377:                if (order != NULL) {
                    378:                        sort = ISC_TRUE;
                    379:                }
                    380:                if (want_random || want_cyclic) {
                    381:                        shuffle = ISC_TRUE;
                    382:                }
                    383:        }
                    384:
                    385:        if ((shuffle || sort) && count > MAX_SHUFFLE) {
                    386:                in = isc_mem_get(cctx->mctx, count * sizeof(*in));
                    387:                out = isc_mem_get(cctx->mctx, count * sizeof(*out));
                    388:                if (in == NULL || out == NULL)
                    389:                        shuffle = sort = ISC_FALSE;
                    390:        }
                    391:
                    392:        if (shuffle || sort) {
                    393:                /*
                    394:                 * First we get handles to all of the rdata.
                    395:                 */
                    396:                i = 0;
                    397:                do {
                    398:                        INSIST(i < count);
                    399:                        dns_rdata_init(&in[i]);
                    400:                        dns_rdataset_current(rdataset, &in[i]);
                    401:                        i++;
                    402:                        result = dns_rdataset_next(rdataset);
                    403:                } while (result == ISC_R_SUCCESS);
                    404:                if (result != ISC_R_NOMORE)
                    405:                        goto cleanup;
                    406:                INSIST(i == count);
                    407:        }
                    408:
                    409:        if (shuffle) {
                    410:                if (want_random) {
                    411:                        /*
                    412:                         * 'Random' order.
                    413:                         */
                    414:                        for (i = 0; i < count; i++) {
                    415:                                isc_uint32_t val;
                    416:
                    417:                                isc_random_get(&val);
                    418:                                choice = i + (val % (count - i));
                    419:                                rdata = in[i];
                    420:                                in[i] = in[choice];
                    421:                                in[choice] = rdata;
                    422:                                if (order != NULL)
                    423:                                        out[i].key = (*order)(&in[i],
                    424:                                                                 order_arg);
                    425:                                else
                    426:                                        out[i].key = 0; /* Unused */
                    427:                                out[i].rdata = &in[i];
                    428:                        }
                    429:                } else if (want_cyclic) {
                    430:                        /*
                    431:                         * 'Cyclic' order.
                    432:                         */
                    433:                        isc_uint32_t val;
                    434:                        unsigned int j;
                    435:
                    436:                        val = rdataset->count;
                    437:                        if (val == ISC_UINT32_MAX)
                    438:                                isc_random_get(&val);
                    439:                        j = val % count;
                    440:                        for (i = 0; i < count; i++) {
                    441:                                if (order != NULL)
                    442:                                        out[i].key = (*order)(&in[j],
                    443:                                                                 order_arg);
                    444:                                else
                    445:                                        out[i].key = 0; /* Unused */
                    446:                                out[i].rdata = &in[j];
                    447:                                j++;
                    448:                                if (j == count)
                    449:                                        j = 0; /* Wrap around. */
                    450:                        }
                    451:                }
                    452:        } else if (sort) {
                    453:                for (i = 0; i < count; i++) {
                    454:                        if (order != NULL)
                    455:                                out[i].key = (*order)(&in[i], order_arg);
                    456:                        else
                    457:                                out[i].key = 0; /* Unused */
                    458:                        out[i].rdata = &in[i];
                    459:                }
                    460:        }
                    461:
                    462:        /*
                    463:         * Sortlist order.
                    464:         */
                    465:        if (sort) {
                    466:                qsort(out, count, sizeof(out[0]), towire_compare);
                    467:        }
                    468:
                    469:        savedbuffer = *target;
                    470:        i = 0;
                    471:        added = 0;
                    472:
                    473:        name = dns_fixedname_initname(&fixed);
                    474:        dns_name_copy(owner_name, name, NULL);
                    475:        dns_rdataset_getownercase(rdataset, name);
                    476:        offset = 0xffff;
                    477:
                    478:        name->attributes |= owner_name->attributes &
                    479:                DNS_NAMEATTR_NOCOMPRESS;
                    480:
                    481:        do {
                    482:                /*
                    483:                 * Copy out the name, type, class, ttl.
                    484:                 */
                    485:
                    486:                rrbuffer = *target;
                    487:                dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
                    488:                result = dns_name_towire2(name, cctx, target, &offset);
                    489:                if (result != ISC_R_SUCCESS)
                    490:                        goto rollback;
                    491:                headlen = sizeof(dns_rdataclass_t) + sizeof(dns_rdatatype_t);
                    492:                if (!question)
                    493:                        headlen += sizeof(dns_ttl_t)
                    494:                                + 2;  /* XXX 2 for rdata len */
                    495:                isc_buffer_availableregion(target, &r);
                    496:                if (r.length < headlen) {
                    497:                        result = ISC_R_NOSPACE;
                    498:                        goto rollback;
                    499:                }
                    500:                isc_buffer_putuint16(target, rdataset->type);
                    501:                isc_buffer_putuint16(target, rdataset->rdclass);
                    502:                if (!question) {
                    503:                        isc_buffer_putuint32(target, rdataset->ttl);
                    504:
                    505:                        /*
                    506:                         * Save space for rdlen.
                    507:                         */
                    508:                        rdlen = *target;
                    509:                        isc_buffer_add(target, 2);
                    510:
                    511:                        /*
                    512:                         * Copy out the rdata
                    513:                         */
                    514:                        if (shuffle || sort) {
                    515:                                rdata = *(out[i].rdata);
                    516:                        } else {
                    517:                                dns_rdata_reset(&rdata);
                    518:                                dns_rdataset_current(rdataset, &rdata);
                    519:                        }
                    520:                        result = dns_rdata_towire(&rdata, cctx, target);
                    521:                        if (result != ISC_R_SUCCESS)
                    522:                                goto rollback;
                    523:                        INSIST((target->used >= rdlen.used + 2) &&
                    524:                               (target->used - rdlen.used - 2 < 65536));
                    525:                        isc_buffer_putuint16(&rdlen,
                    526:                                             (isc_uint16_t)(target->used -
                    527:                                                            rdlen.used - 2));
                    528:                        added++;
                    529:                }
                    530:
                    531:                if (shuffle || sort) {
                    532:                        i++;
                    533:                        if (i == count)
                    534:                                result = ISC_R_NOMORE;
                    535:                        else
                    536:                                result = ISC_R_SUCCESS;
                    537:                } else {
                    538:                        result = dns_rdataset_next(rdataset);
                    539:                }
                    540:        } while (result == ISC_R_SUCCESS);
                    541:
                    542:        if (result != ISC_R_NOMORE)
                    543:                goto rollback;
                    544:
                    545:        *countp += count;
                    546:
                    547:        result = ISC_R_SUCCESS;
                    548:        goto cleanup;
                    549:
                    550:  rollback:
                    551:        if (partial && result == ISC_R_NOSPACE) {
                    552:                INSIST(rrbuffer.used < 65536);
                    553:                dns_compress_rollback(cctx, (isc_uint16_t)rrbuffer.used);
                    554:                *countp += added;
                    555:                *target = rrbuffer;
                    556:                goto cleanup;
                    557:        }
                    558:        INSIST(savedbuffer.used < 65536);
                    559:        dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
                    560:        *countp = 0;
                    561:        *target = savedbuffer;
                    562:
                    563:  cleanup:
                    564:        if (out != NULL && out != out_fixed)
                    565:                isc_mem_put(cctx->mctx, out, count * sizeof(*out));
                    566:        if (in != NULL && in != in_fixed)
                    567:                isc_mem_put(cctx->mctx, in, count * sizeof(*in));
                    568:        return (result);
                    569: }
                    570:
                    571: isc_result_t
                    572: dns_rdataset_towiresorted(dns_rdataset_t *rdataset,
                    573:                          const dns_name_t *owner_name,
                    574:                          dns_compress_t *cctx,
                    575:                          isc_buffer_t *target,
                    576:                          dns_rdatasetorderfunc_t order,
                    577:                          const void *order_arg,
                    578:                          unsigned int options,
                    579:                          unsigned int *countp)
                    580: {
                    581:        return (towiresorted(rdataset, owner_name, cctx, target,
                    582:                             order, order_arg, ISC_FALSE, options,
                    583:                             countp, NULL));
                    584: }
                    585:
                    586: isc_result_t
                    587: dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
                    588:                           const dns_name_t *owner_name,
                    589:                           dns_compress_t *cctx,
                    590:                           isc_buffer_t *target,
                    591:                           dns_rdatasetorderfunc_t order,
                    592:                           const void *order_arg,
                    593:                           unsigned int options,
                    594:                           unsigned int *countp,
                    595:                           void **state)
                    596: {
                    597:        REQUIRE(state == NULL); /* XXX remove when implemented */
                    598:        return (towiresorted(rdataset, owner_name, cctx, target,
                    599:                             order, order_arg, ISC_TRUE, options,
                    600:                             countp, state));
                    601: }
                    602:
                    603: isc_result_t
                    604: dns_rdataset_towire(dns_rdataset_t *rdataset,
                    605:                    const dns_name_t *owner_name,
                    606:                    dns_compress_t *cctx,
                    607:                    isc_buffer_t *target,
                    608:                    unsigned int options,
                    609:                    unsigned int *countp)
                    610: {
                    611:        return (towiresorted(rdataset, owner_name, cctx, target,
                    612:                             NULL, NULL, ISC_FALSE, options, countp, NULL));
                    613: }
                    614:
                    615: isc_result_t
                    616: dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
                    617:                            dns_additionaldatafunc_t add, void *arg)
                    618: {
                    619:        dns_rdata_t rdata = DNS_RDATA_INIT;
                    620:        isc_result_t result;
                    621:
                    622:        /*
                    623:         * For each rdata in rdataset, call 'add' for each name and type in the
                    624:         * rdata which is subject to additional section processing.
                    625:         */
                    626:
                    627:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    628:        REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
                    629:
                    630:        result = dns_rdataset_first(rdataset);
                    631:        if (result != ISC_R_SUCCESS)
                    632:                return (result);
                    633:
                    634:        do {
                    635:                dns_rdataset_current(rdataset, &rdata);
                    636:                result = dns_rdata_additionaldata(&rdata, add, arg);
                    637:                if (result == ISC_R_SUCCESS)
                    638:                        result = dns_rdataset_next(rdataset);
                    639:                dns_rdata_reset(&rdata);
                    640:        } while (result == ISC_R_SUCCESS);
                    641:
                    642:        if (result != ISC_R_NOMORE)
                    643:                return (result);
                    644:
                    645:        return (ISC_R_SUCCESS);
                    646: }
                    647:
                    648: isc_result_t
                    649: dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
                    650:
                    651:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    652:        REQUIRE(rdataset->methods != NULL);
                    653:        if (rdataset->methods->addnoqname == NULL)
                    654:                return (ISC_R_NOTIMPLEMENTED);
                    655:        return((rdataset->methods->addnoqname)(rdataset, name));
                    656: }
                    657:
                    658: isc_result_t
                    659: dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
                    660:                        dns_rdataset_t *neg, dns_rdataset_t *negsig)
                    661: {
                    662:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    663:        REQUIRE(rdataset->methods != NULL);
                    664:
                    665:        if (rdataset->methods->getnoqname == NULL)
                    666:                return (ISC_R_NOTIMPLEMENTED);
                    667:        return((rdataset->methods->getnoqname)(rdataset, name, neg, negsig));
                    668: }
                    669:
                    670: isc_result_t
                    671: dns_rdataset_addclosest(dns_rdataset_t *rdataset, const dns_name_t *name) {
                    672:
                    673:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    674:        REQUIRE(rdataset->methods != NULL);
                    675:        if (rdataset->methods->addclosest == NULL)
                    676:                return (ISC_R_NOTIMPLEMENTED);
                    677:        return((rdataset->methods->addclosest)(rdataset, name));
                    678: }
                    679:
                    680: isc_result_t
                    681: dns_rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
                    682:                        dns_rdataset_t *neg, dns_rdataset_t *negsig)
                    683: {
                    684:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    685:        REQUIRE(rdataset->methods != NULL);
                    686:
                    687:        if (rdataset->methods->getclosest == NULL)
                    688:                return (ISC_R_NOTIMPLEMENTED);
                    689:        return((rdataset->methods->getclosest)(rdataset, name, neg, negsig));
                    690: }
                    691:
                    692: void
                    693: dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
                    694:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    695:        REQUIRE(rdataset->methods != NULL);
                    696:
                    697:        if (rdataset->methods->settrust != NULL)
                    698:                (rdataset->methods->settrust)(rdataset, trust);
                    699:        else
                    700:                rdataset->trust = trust;
                    701: }
                    702:
                    703: void
                    704: dns_rdataset_expire(dns_rdataset_t *rdataset) {
                    705:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    706:        REQUIRE(rdataset->methods != NULL);
                    707:
                    708:        if (rdataset->methods->expire != NULL)
                    709:                (rdataset->methods->expire)(rdataset);
                    710: }
                    711:
                    712: void
                    713: dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) {
                    714:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    715:        REQUIRE(rdataset->methods != NULL);
                    716:
                    717:        if (rdataset->methods->clearprefetch != NULL)
                    718:                (rdataset->methods->clearprefetch)(rdataset);
                    719: }
                    720:
                    721: void
                    722: dns_rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
                    723:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    724:        REQUIRE(rdataset->methods != NULL);
                    725:
                    726:        if (rdataset->methods->setownercase != NULL)
                    727:                (rdataset->methods->setownercase)(rdataset, name);
                    728: }
                    729:
                    730: void
                    731: dns_rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
                    732:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    733:        REQUIRE(rdataset->methods != NULL);
                    734:
                    735:        if (rdataset->methods->getownercase != NULL)
                    736:                (rdataset->methods->getownercase)(rdataset, name);
                    737: }
                    738:
                    739: void
                    740: dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
                    741:                     dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
                    742:                     isc_boolean_t acceptexpired)
                    743: {
                    744:        isc_uint32_t ttl = 0;
                    745:
                    746:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    747:        REQUIRE(DNS_RDATASET_VALID(sigrdataset));
                    748:        REQUIRE(rrsig != NULL);
                    749:
                    750:        /*
                    751:         * If we accept expired RRsets keep them for no more than 120 seconds.
                    752:         */
                    753:        if (acceptexpired &&
                    754:            (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) ||
                    755:             isc_serial_le(rrsig->timeexpire, now)))
                    756:                ttl = 120;
                    757:        else if (isc_serial_ge(rrsig->timeexpire, now))
                    758:                ttl = rrsig->timeexpire - now;
                    759:
                    760:        ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl),
                    761:                      ISC_MIN(rrsig->originalttl, ttl));
                    762:        rdataset->ttl = ttl;
                    763:        sigrdataset->ttl = ttl;
                    764: }
                    765:
                    766: isc_result_t
                    767: dns_rdataset_addglue(dns_rdataset_t *rdataset,
                    768:                     dns_dbversion_t *version,
                    769:                     unsigned int options,
                    770:                     dns_message_t *msg)
                    771: {
                    772:        REQUIRE(DNS_RDATASET_VALID(rdataset));
                    773:        REQUIRE(rdataset->methods != NULL);
                    774:        REQUIRE(rdataset->type == dns_rdatatype_ns);
                    775:
                    776:        if (rdataset->methods->addglue == NULL)
                    777:                return (ISC_R_NOTIMPLEMENTED);
                    778:
                    779:        return ((rdataset->methods->addglue)(rdataset, version,
                    780:                                             options, msg));
                    781: }

CVSweb <webmaster@jp.NetBSD.org>