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

Annotation of src/external/mpl/bind/dist/lib/dns/tests/dnstest.c, Revision 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 <atf-c.h>
        !            19:
        !            20: #include <stdlib.h>
        !            21: #include <time.h>
        !            22: #include <unistd.h>
        !            23:
        !            24: #include <isc/app.h>
        !            25: #include <isc/buffer.h>
        !            26: #include <isc/entropy.h>
        !            27: #include <isc/file.h>
        !            28: #include <isc/hash.h>
        !            29: #include <isc/hex.h>
        !            30: #include <isc/lex.h>
        !            31: #include <isc/mem.h>
        !            32: #include <isc/os.h>
        !            33: #include <isc/print.h>
        !            34: #include <isc/string.h>
        !            35: #include <isc/socket.h>
        !            36: #include <isc/stdio.h>
        !            37: #include <isc/task.h>
        !            38: #include <isc/timer.h>
        !            39: #include <isc/util.h>
        !            40:
        !            41: #include <dns/db.h>
        !            42: #include <dns/fixedname.h>
        !            43: #include <dns/log.h>
        !            44: #include <dns/name.h>
        !            45: #include <dns/result.h>
        !            46: #include <dns/view.h>
        !            47: #include <dns/zone.h>
        !            48:
        !            49: #include "dnstest.h"
        !            50:
        !            51: isc_mem_t *mctx = NULL;
        !            52: isc_entropy_t *ectx = NULL;
        !            53: isc_log_t *lctx = NULL;
        !            54: isc_taskmgr_t *taskmgr = NULL;
        !            55: isc_task_t *maintask = NULL;
        !            56: isc_timermgr_t *timermgr = NULL;
        !            57: isc_socketmgr_t *socketmgr = NULL;
        !            58: dns_zonemgr_t *zonemgr = NULL;
        !            59: isc_boolean_t app_running = ISC_FALSE;
        !            60: int ncpus;
        !            61: isc_boolean_t debug_mem_record = ISC_TRUE;
        !            62:
        !            63: static isc_boolean_t hash_active = ISC_FALSE, dst_active = ISC_FALSE;
        !            64:
        !            65: /*
        !            66:  * Logging categories: this needs to match the list in bin/named/log.c.
        !            67:  */
        !            68: static isc_logcategory_t categories[] = {
        !            69:                { "",                0 },
        !            70:                { "client",          0 },
        !            71:                { "network",         0 },
        !            72:                { "update",          0 },
        !            73:                { "queries",         0 },
        !            74:                { "unmatched",       0 },
        !            75:                { "update-security", 0 },
        !            76:                { "query-errors",    0 },
        !            77:                { NULL,              0 }
        !            78: };
        !            79:
        !            80: static void
        !            81: cleanup_managers(void) {
        !            82:        if (app_running)
        !            83:                isc_app_finish();
        !            84:        if (socketmgr != NULL)
        !            85:                isc_socketmgr_destroy(&socketmgr);
        !            86:        if (maintask != NULL)
        !            87:                isc_task_destroy(&maintask);
        !            88:        if (taskmgr != NULL)
        !            89:                isc_taskmgr_destroy(&taskmgr);
        !            90:        if (timermgr != NULL)
        !            91:                isc_timermgr_destroy(&timermgr);
        !            92: }
        !            93:
        !            94: static isc_result_t
        !            95: create_managers(void) {
        !            96:        isc_result_t result;
        !            97: #ifdef ISC_PLATFORM_USETHREADS
        !            98:        ncpus = isc_os_ncpus();
        !            99: #else
        !           100:        ncpus = 1;
        !           101: #endif
        !           102:
        !           103:        CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
        !           104:        CHECK(isc_timermgr_create(mctx, &timermgr));
        !           105:        CHECK(isc_socketmgr_create(mctx, &socketmgr));
        !           106:        CHECK(isc_task_create(taskmgr, 0, &maintask));
        !           107:        return (ISC_R_SUCCESS);
        !           108:
        !           109:  cleanup:
        !           110:        cleanup_managers();
        !           111:        return (result);
        !           112: }
        !           113:
        !           114: isc_result_t
        !           115: dns_test_begin(FILE *logfile, isc_boolean_t start_managers) {
        !           116:        isc_result_t result;
        !           117:
        !           118:        if (start_managers)
        !           119:                CHECK(isc_app_start());
        !           120:        if (debug_mem_record)
        !           121:                isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
        !           122:        CHECK(isc_mem_create(0, 0, &mctx));
        !           123:        CHECK(isc_entropy_create(mctx, &ectx));
        !           124:
        !           125:        CHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING));
        !           126:        dst_active = ISC_TRUE;
        !           127:
        !           128:        CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE));
        !           129:        hash_active = ISC_TRUE;
        !           130:
        !           131:        if (logfile != NULL) {
        !           132:                isc_logdestination_t destination;
        !           133:                isc_logconfig_t *logconfig = NULL;
        !           134:
        !           135:                CHECK(isc_log_create(mctx, &lctx, &logconfig));
        !           136:                isc_log_registercategories(lctx, categories);
        !           137:                isc_log_setcontext(lctx);
        !           138:                dns_log_init(lctx);
        !           139:                dns_log_setcontext(lctx);
        !           140:
        !           141:                destination.file.stream = logfile;
        !           142:                destination.file.name = NULL;
        !           143:                destination.file.versions = ISC_LOG_ROLLNEVER;
        !           144:                destination.file.maximum_size = 0;
        !           145:                CHECK(isc_log_createchannel(logconfig, "stderr",
        !           146:                                            ISC_LOG_TOFILEDESC,
        !           147:                                            ISC_LOG_DYNAMIC,
        !           148:                                            &destination, 0));
        !           149:                CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL));
        !           150:        }
        !           151:
        !           152:        dns_result_register();
        !           153:
        !           154:        if (start_managers)
        !           155:                CHECK(create_managers());
        !           156:
        !           157:        /*
        !           158:         * atf-run changes us to a /tmp directory, so tests
        !           159:         * that access test data files must first chdir to the proper
        !           160:         * location.
        !           161:         */
        !           162:        if (chdir(TESTS) == -1)
        !           163:                CHECK(ISC_R_FAILURE);
        !           164:
        !           165:        return (ISC_R_SUCCESS);
        !           166:
        !           167:  cleanup:
        !           168:        dns_test_end();
        !           169:        return (result);
        !           170: }
        !           171:
        !           172: void
        !           173: dns_test_end(void) {
        !           174:        if (hash_active) {
        !           175:                isc_hash_destroy();
        !           176:                hash_active = ISC_FALSE;
        !           177:        }
        !           178:        if (dst_active) {
        !           179:                dst_lib_destroy();
        !           180:                dst_active = ISC_FALSE;
        !           181:        }
        !           182:        if (ectx != NULL)
        !           183:                isc_entropy_detach(&ectx);
        !           184:
        !           185:        cleanup_managers();
        !           186:
        !           187:        if (lctx != NULL)
        !           188:                isc_log_destroy(&lctx);
        !           189:
        !           190:        if (mctx != NULL)
        !           191:                isc_mem_destroy(&mctx);
        !           192: }
        !           193:
        !           194: /*
        !           195:  * Create a view.
        !           196:  */
        !           197: isc_result_t
        !           198: dns_test_makeview(const char *name, dns_view_t **viewp) {
        !           199:        isc_result_t result;
        !           200:        dns_view_t *view = NULL;
        !           201:
        !           202:        CHECK(dns_view_create(mctx, dns_rdataclass_in, name, &view));
        !           203:        *viewp = view;
        !           204:
        !           205:        return (ISC_R_SUCCESS);
        !           206:
        !           207:  cleanup:
        !           208:        if (view != NULL)
        !           209:                dns_view_detach(&view);
        !           210:        return (result);
        !           211: }
        !           212:
        !           213: isc_result_t
        !           214: dns_test_makezone(const char *name, dns_zone_t **zonep, dns_view_t *view,
        !           215:                  isc_boolean_t createview)
        !           216: {
        !           217:        dns_fixedname_t fixed_origin;
        !           218:        dns_zone_t *zone = NULL;
        !           219:        isc_result_t result;
        !           220:        dns_name_t *origin;
        !           221:
        !           222:        REQUIRE(view == NULL || !createview);
        !           223:
        !           224:        /*
        !           225:         * Create the zone structure.
        !           226:         */
        !           227:        result = dns_zone_create(&zone, mctx);
        !           228:        if (result != ISC_R_SUCCESS) {
        !           229:                return (result);
        !           230:        }
        !           231:
        !           232:        /*
        !           233:         * Set zone type and origin.
        !           234:         */
        !           235:        dns_zone_settype(zone, dns_zone_master);
        !           236:        origin = dns_fixedname_initname(&fixed_origin);
        !           237:        result = dns_name_fromstring(origin, name, 0, NULL);
        !           238:        if (result != ISC_R_SUCCESS) {
        !           239:                goto detach_zone;
        !           240:        }
        !           241:        result = dns_zone_setorigin(zone, origin);
        !           242:        if (result != ISC_R_SUCCESS) {
        !           243:                goto detach_zone;
        !           244:        }
        !           245:
        !           246:        /*
        !           247:         * If requested, create a view.
        !           248:         */
        !           249:        if (createview) {
        !           250:                result = dns_test_makeview("view", &view);
        !           251:                if (result != ISC_R_SUCCESS) {
        !           252:                        goto detach_zone;
        !           253:                }
        !           254:        }
        !           255:
        !           256:        /*
        !           257:         * If a view was passed as an argument or created above, attach the
        !           258:         * created zone to it.  Otherwise, set the zone's class to IN.
        !           259:         */
        !           260:        if (view != NULL) {
        !           261:                dns_zone_setview(zone, view);
        !           262:                dns_zone_setclass(zone, view->rdclass);
        !           263:                dns_view_addzone(view, zone);
        !           264:        } else {
        !           265:                dns_zone_setclass(zone, dns_rdataclass_in);
        !           266:        }
        !           267:
        !           268:        *zonep = zone;
        !           269:
        !           270:        return (ISC_R_SUCCESS);
        !           271:
        !           272:  detach_zone:
        !           273:        dns_zone_detach(&zone);
        !           274:
        !           275:        return (result);
        !           276: }
        !           277:
        !           278: isc_result_t
        !           279: dns_test_setupzonemgr(void) {
        !           280:        isc_result_t result;
        !           281:        REQUIRE(zonemgr == NULL);
        !           282:
        !           283:        result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr,
        !           284:                                    &zonemgr);
        !           285:        return (result);
        !           286: }
        !           287:
        !           288: isc_result_t
        !           289: dns_test_managezone(dns_zone_t *zone) {
        !           290:        isc_result_t result;
        !           291:        REQUIRE(zonemgr != NULL);
        !           292:
        !           293:        result = dns_zonemgr_setsize(zonemgr, 1);
        !           294:        if (result != ISC_R_SUCCESS)
        !           295:                return (result);
        !           296:
        !           297:        result = dns_zonemgr_managezone(zonemgr, zone);
        !           298:        return (result);
        !           299: }
        !           300:
        !           301: void
        !           302: dns_test_releasezone(dns_zone_t *zone) {
        !           303:        REQUIRE(zonemgr != NULL);
        !           304:        dns_zonemgr_releasezone(zonemgr, zone);
        !           305: }
        !           306:
        !           307: void
        !           308: dns_test_closezonemgr(void) {
        !           309:        REQUIRE(zonemgr != NULL);
        !           310:
        !           311:        dns_zonemgr_shutdown(zonemgr);
        !           312:        dns_zonemgr_detach(&zonemgr);
        !           313: }
        !           314:
        !           315: /*
        !           316:  * Sleep for 'usec' microseconds.
        !           317:  */
        !           318: void
        !           319: dns_test_nap(isc_uint32_t usec) {
        !           320: #ifdef HAVE_NANOSLEEP
        !           321:        struct timespec ts;
        !           322:
        !           323:        ts.tv_sec = usec / 1000000;
        !           324:        ts.tv_nsec = (usec % 1000000) * 1000;
        !           325:        nanosleep(&ts, NULL);
        !           326: #elif HAVE_USLEEP
        !           327:        usleep(usec);
        !           328: #else
        !           329:        /*
        !           330:         * No fractional-second sleep function is available, so we
        !           331:         * round up to the nearest second and sleep instead
        !           332:         */
        !           333:        sleep((usec / 1000000) + 1);
        !           334: #endif
        !           335: }
        !           336:
        !           337: isc_result_t
        !           338: dns_test_loaddb(dns_db_t **db, dns_dbtype_t dbtype, const char *origin,
        !           339:                const char *testfile)
        !           340: {
        !           341:        isc_result_t            result;
        !           342:        dns_fixedname_t         fixed;
        !           343:        dns_name_t              *name;
        !           344:
        !           345:        name = dns_fixedname_initname(&fixed);
        !           346:
        !           347:        result = dns_name_fromstring(name, origin, 0, NULL);
        !           348:        if (result != ISC_R_SUCCESS)
        !           349:                return(result);
        !           350:
        !           351:        result = dns_db_create(mctx, "rbt", name, dbtype, dns_rdataclass_in,
        !           352:                               0, NULL, db);
        !           353:        if (result != ISC_R_SUCCESS)
        !           354:                return (result);
        !           355:
        !           356:        result = dns_db_load(*db, testfile);
        !           357:        return (result);
        !           358: }
        !           359:
        !           360: static int
        !           361: fromhex(char c) {
        !           362:        if (c >= '0' && c <= '9')
        !           363:                return (c - '0');
        !           364:        else if (c >= 'a' && c <= 'f')
        !           365:                return (c - 'a' + 10);
        !           366:        else if (c >= 'A' && c <= 'F')
        !           367:                return (c - 'A' + 10);
        !           368:
        !           369:        printf("bad input format: %02x\n", c);
        !           370:        exit(3);
        !           371:        /* NOTREACHED */
        !           372: }
        !           373:
        !           374: /*
        !           375:  * Format contents of given memory region as a hex string, using the buffer
        !           376:  * of length 'buflen' pointed to by 'buf'. 'buflen' must be at least three
        !           377:  * times 'len'. Always returns 'buf'.
        !           378:  */
        !           379: char *
        !           380: dns_test_tohex(const unsigned char *data, size_t len, char *buf, size_t buflen)
        !           381: {
        !           382:        isc_constregion_t source = {
        !           383:                .base = data,
        !           384:                .length = len
        !           385:        };
        !           386:        isc_buffer_t target;
        !           387:        isc_result_t result;
        !           388:
        !           389:        memset(buf, 0, buflen);
        !           390:        isc_buffer_init(&target, buf, buflen);
        !           391:        result = isc_hex_totext((isc_region_t *)&source, 1, " ", &target);
        !           392:        ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
        !           393:
        !           394:        return (buf);
        !           395: }
        !           396:
        !           397: isc_result_t
        !           398: dns_test_getdata(const char *file, unsigned char *buf,
        !           399:                 size_t bufsiz, size_t *sizep)
        !           400: {
        !           401:        isc_result_t result;
        !           402:        unsigned char *bp;
        !           403:        char *rp, *wp;
        !           404:        char s[BUFSIZ];
        !           405:        size_t len, i;
        !           406:        FILE *f = NULL;
        !           407:        int n;
        !           408:
        !           409:        result = isc_stdio_open(file, "r", &f);
        !           410:        if (result != ISC_R_SUCCESS)
        !           411:                return (result);
        !           412:
        !           413:        bp = buf;
        !           414:        while (fgets(s, sizeof(s), f) != NULL) {
        !           415:                rp = s;
        !           416:                wp = s;
        !           417:                len = 0;
        !           418:                while (*rp != '\0') {
        !           419:                        if (*rp == '#')
        !           420:                                break;
        !           421:                        if (*rp != ' ' && *rp != '\t' &&
        !           422:                            *rp != '\r' && *rp != '\n') {
        !           423:                                *wp++ = *rp;
        !           424:                                len++;
        !           425:                        }
        !           426:                        rp++;
        !           427:                }
        !           428:                if (len == 0U)
        !           429:                        continue;
        !           430:                if (len % 2 != 0U)
        !           431:                        CHECK(ISC_R_UNEXPECTEDEND);
        !           432:                if (len > bufsiz * 2)
        !           433:                        CHECK(ISC_R_NOSPACE);
        !           434:                rp = s;
        !           435:                for (i = 0; i < len; i += 2) {
        !           436:                        n = fromhex(*rp++);
        !           437:                        n *= 16;
        !           438:                        n += fromhex(*rp++);
        !           439:                        *bp++ = n;
        !           440:                }
        !           441:        }
        !           442:
        !           443:
        !           444:        *sizep = bp - buf;
        !           445:
        !           446:        result = ISC_R_SUCCESS;
        !           447:
        !           448:  cleanup:
        !           449:        isc_stdio_close(f);
        !           450:        return (result);
        !           451: }
        !           452:
        !           453: isc_result_t
        !           454: dns_test_rdatafromstring(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
        !           455:                         dns_rdatatype_t rdtype, unsigned char *dst,
        !           456:                         size_t dstlen, const char *src)
        !           457: {
        !           458:        isc_buffer_t source, target;
        !           459:        isc_lex_t *lex = NULL;
        !           460:        isc_result_t result;
        !           461:        size_t length;
        !           462:
        !           463:        REQUIRE(rdata != NULL);
        !           464:        REQUIRE(DNS_RDATA_INITIALIZED(rdata));
        !           465:        REQUIRE(dst != NULL);
        !           466:        REQUIRE(src != NULL);
        !           467:
        !           468:        /*
        !           469:         * Set up source to hold the input string.
        !           470:         */
        !           471:        length = strlen(src);
        !           472:        isc_buffer_constinit(&source, src, length);
        !           473:        isc_buffer_add(&source, length);
        !           474:
        !           475:        /*
        !           476:         * Create a lexer as one is required by dns_rdata_fromtext().
        !           477:         */
        !           478:        result = isc_lex_create(mctx, 64, &lex);
        !           479:        if (result != ISC_R_SUCCESS) {
        !           480:                return (result);
        !           481:        }
        !           482:
        !           483:        /*
        !           484:         * Point lexer at source.
        !           485:         */
        !           486:        result = isc_lex_openbuffer(lex, &source);
        !           487:        if (result != ISC_R_SUCCESS) {
        !           488:                goto destroy_lexer;
        !           489:        }
        !           490:
        !           491:        /*
        !           492:         * Set up target for storing uncompressed wire form of provided RDATA.
        !           493:         */
        !           494:        isc_buffer_init(&target, dst, dstlen);
        !           495:
        !           496:        /*
        !           497:         * Parse input string, determining result.
        !           498:         */
        !           499:        result = dns_rdata_fromtext(rdata, rdclass, rdtype, lex, dns_rootname,
        !           500:                                    0, NULL, &target, NULL);
        !           501:
        !           502:  destroy_lexer:
        !           503:        isc_lex_destroy(&lex);
        !           504:
        !           505:        return (result);
        !           506: }
        !           507:
        !           508: void
        !           509: dns_test_namefromstring(const char *namestr, dns_fixedname_t *fname) {
        !           510:        size_t length;
        !           511:        isc_buffer_t *b = NULL;
        !           512:        isc_result_t result;
        !           513:        dns_name_t *name;
        !           514:
        !           515:        length = strlen(namestr);
        !           516:
        !           517:        result = isc_buffer_allocate(mctx, &b, length);
        !           518:        ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
        !           519:        isc_buffer_putmem(b, (const unsigned char *) namestr, length);
        !           520:
        !           521:        name = dns_fixedname_initname(fname);
        !           522:        ATF_REQUIRE(name != NULL);
        !           523:        result = dns_name_fromtext(name, b, dns_rootname, 0, NULL);
        !           524:        ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
        !           525:
        !           526:        isc_buffer_free(&b);
        !           527: }
        !           528:
        !           529: isc_result_t
        !           530: dns_test_difffromchanges(dns_diff_t *diff, const zonechange_t *changes) {
        !           531:        isc_result_t result = ISC_R_SUCCESS;
        !           532:        unsigned char rdata_buf[1024];
        !           533:        dns_difftuple_t *tuple = NULL;
        !           534:        isc_consttextregion_t region;
        !           535:        dns_rdatatype_t rdatatype;
        !           536:        dns_fixedname_t fixedname;
        !           537:        dns_rdata_t rdata;
        !           538:        dns_name_t *name;
        !           539:        size_t i;
        !           540:
        !           541:        REQUIRE(diff != NULL);
        !           542:        REQUIRE(changes != NULL);
        !           543:
        !           544:        dns_diff_init(mctx, diff);
        !           545:
        !           546:        for (i = 0; changes[i].owner != NULL; i++) {
        !           547:                /*
        !           548:                 * Parse owner name.
        !           549:                 */
        !           550:                name = dns_fixedname_initname(&fixedname);
        !           551:                result = dns_name_fromstring(name, changes[i].owner, 0, mctx);
        !           552:                if (result != ISC_R_SUCCESS) {
        !           553:                        break;
        !           554:                }
        !           555:
        !           556:                /*
        !           557:                 * Parse RDATA type.
        !           558:                 */
        !           559:                region.base = changes[i].type;
        !           560:                region.length = strlen(changes[i].type);
        !           561:                result = dns_rdatatype_fromtext(&rdatatype,
        !           562:                                                (isc_textregion_t *)&region);
        !           563:                if (result != ISC_R_SUCCESS) {
        !           564:                        break;
        !           565:                }
        !           566:
        !           567:                /*
        !           568:                 * Parse RDATA.
        !           569:                 */
        !           570:                dns_rdata_init(&rdata);
        !           571:                result = dns_test_rdatafromstring(&rdata, dns_rdataclass_in,
        !           572:                                                  rdatatype, rdata_buf,
        !           573:                                                  sizeof(rdata_buf),
        !           574:                                                  changes[i].rdata);
        !           575:                if (result != ISC_R_SUCCESS) {
        !           576:                        break;
        !           577:                }
        !           578:
        !           579:                /*
        !           580:                 * Create a diff tuple for the parsed change and append it to
        !           581:                 * the diff.
        !           582:                 */
        !           583:                result = dns_difftuple_create(mctx, changes[i].op, name,
        !           584:                                              changes[i].ttl, &rdata, &tuple);
        !           585:                if (result != ISC_R_SUCCESS) {
        !           586:                        break;
        !           587:                }
        !           588:                dns_diff_append(diff, &tuple);
        !           589:        }
        !           590:
        !           591:        if (result != ISC_R_SUCCESS) {
        !           592:                dns_diff_clear(diff);
        !           593:        }
        !           594:
        !           595:        return (result);
        !           596: }

CVSweb <webmaster@jp.NetBSD.org>