[BACK]Return to dispatch_test.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/dispatch_test.c, Revision 1.4.4.1

1.4.4.1 ! martin      1: /*     $NetBSD: dispatch_test.c,v 1.5 2019/09/05 19:32:58 christos Exp $       */
1.1       christos    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: #include <config.h>
                     15:
1.3       christos   16: #if HAVE_CMOCKA
1.1       christos   17:
1.3       christos   18: #include <stdarg.h>
                     19: #include <stddef.h>
                     20: #include <setjmp.h>
                     21:
                     22: #include <inttypes.h>
1.4.4.1 ! martin     23: #include <sched.h> /* IWYU pragma: keep */
1.3       christos   24: #include <stdbool.h>
                     25: #include <stdlib.h>
                     26: #include <string.h>
1.1       christos   27: #include <unistd.h>
                     28:
1.3       christos   29: #define UNIT_TESTING
                     30: #include <cmocka.h>
                     31:
1.1       christos   32: #include <isc/app.h>
                     33: #include <isc/buffer.h>
                     34: #include <isc/socket.h>
                     35: #include <isc/task.h>
                     36: #include <isc/timer.h>
1.3       christos   37: #include <isc/util.h>
1.1       christos   38:
                     39: #include <dns/dispatch.h>
                     40: #include <dns/name.h>
                     41: #include <dns/view.h>
                     42:
                     43: #include "dnstest.h"
                     44:
                     45: dns_dispatchmgr_t *dispatchmgr = NULL;
                     46: dns_dispatchset_t *dset = NULL;
                     47:
1.3       christos   48: static int
                     49: _setup(void **state) {
                     50:        isc_result_t result;
                     51:
                     52:        UNUSED(state);
                     53:
                     54:        result = dns_test_begin(NULL, true);
                     55:        assert_int_equal(result, ISC_R_SUCCESS);
                     56:
                     57:        return (0);
                     58: }
                     59:
                     60: static int
                     61: _teardown(void **state) {
                     62:        UNUSED(state);
                     63:
                     64:        dns_test_end();
                     65:
                     66:        return (0);
                     67: }
                     68:
1.1       christos   69: static isc_result_t
                     70: make_dispatchset(unsigned int ndisps) {
                     71:        isc_result_t result;
                     72:        isc_sockaddr_t any;
                     73:        unsigned int attrs;
                     74:        dns_dispatch_t *disp = NULL;
                     75:
1.3       christos   76:        result = dns_dispatchmgr_create(mctx, &dispatchmgr);
1.1       christos   77:        if (result != ISC_R_SUCCESS)
                     78:                return (result);
                     79:
                     80:        isc_sockaddr_any(&any);
                     81:        attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP;
                     82:        result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
                     83:                                     &any, 512, 6, 1024, 17, 19, attrs,
                     84:                                     attrs, &disp);
                     85:        if (result != ISC_R_SUCCESS)
                     86:                return (result);
                     87:
                     88:        result = dns_dispatchset_create(mctx, socketmgr, taskmgr, disp,
                     89:                                        &dset, ndisps);
                     90:        dns_dispatch_detach(&disp);
                     91:
                     92:        return (result);
                     93: }
                     94:
                     95: static void
1.3       christos   96: reset(void) {
                     97:        if (dset != NULL) {
1.1       christos   98:                dns_dispatchset_destroy(&dset);
1.3       christos   99:        }
                    100:        if (dispatchmgr != NULL) {
1.1       christos  101:                dns_dispatchmgr_destroy(&dispatchmgr);
1.3       christos  102:        }
1.1       christos  103: }
                    104:
1.3       christos  105: /* create dispatch set */
                    106: static void
                    107: dispatchset_create(void **state) {
1.1       christos  108:        isc_result_t result;
                    109:
1.3       christos  110:        UNUSED(state);
1.1       christos  111:
                    112:        result = make_dispatchset(1);
1.3       christos  113:        assert_int_equal(result, ISC_R_SUCCESS);
                    114:        reset();
1.1       christos  115:
                    116:        result = make_dispatchset(10);
1.3       christos  117:        assert_int_equal(result, ISC_R_SUCCESS);
                    118:        reset();
1.1       christos  119: }
                    120:
1.3       christos  121: /* test dispatch set round-robin */
                    122: static void
                    123: dispatchset_get(void **state) {
1.1       christos  124:        isc_result_t result;
                    125:        dns_dispatch_t *d1, *d2, *d3, *d4, *d5;
                    126:
1.3       christos  127:        UNUSED(state);
1.1       christos  128:
                    129:        result = make_dispatchset(1);
1.3       christos  130:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  131:
                    132:        d1 = dns_dispatchset_get(dset);
                    133:        d2 = dns_dispatchset_get(dset);
                    134:        d3 = dns_dispatchset_get(dset);
                    135:        d4 = dns_dispatchset_get(dset);
                    136:        d5 = dns_dispatchset_get(dset);
                    137:
1.3       christos  138:        assert_int_equal(d1, d2);
                    139:        assert_int_equal(d2, d3);
                    140:        assert_int_equal(d3, d4);
                    141:        assert_int_equal(d4, d5);
1.1       christos  142:
1.3       christos  143:        reset();
1.1       christos  144:
                    145:        result = make_dispatchset(4);
1.3       christos  146:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  147:
                    148:        d1 = dns_dispatchset_get(dset);
                    149:        d2 = dns_dispatchset_get(dset);
                    150:        d3 = dns_dispatchset_get(dset);
                    151:        d4 = dns_dispatchset_get(dset);
                    152:        d5 = dns_dispatchset_get(dset);
                    153:
1.3       christos  154:        assert_int_equal(d1, d5);
                    155:        assert_true(d1 != d2);
                    156:        assert_true(d2 != d3);
                    157:        assert_true(d3 != d4);
                    158:        assert_true(d4 != d5);
1.1       christos  159:
1.3       christos  160:        reset();
1.1       christos  161: }
                    162:
                    163: static void
                    164: senddone(isc_task_t *task, isc_event_t *event) {
                    165:        isc_socket_t *sock = event->ev_arg;
                    166:
                    167:        UNUSED(task);
                    168:
                    169:        isc_socket_detach(&sock);
                    170:        isc_event_free(&event);
                    171: }
                    172:
                    173: static void
                    174: nameserver(isc_task_t *task, isc_event_t *event) {
                    175:        isc_result_t result;
                    176:        isc_region_t region;
                    177:        isc_socket_t *dummy;
                    178:        isc_socket_t *sock = event->ev_arg;
                    179:        isc_socketevent_t *ev = (isc_socketevent_t *)event;
                    180:        static unsigned char buf1[16];
                    181:        static unsigned char buf2[16];
                    182:
                    183:        memmove(buf1, ev->region.base, 12);
                    184:        memset(buf1 + 12, 0, 4);
                    185:        buf1[2] |= 0x80;        /* qr=1 */
                    186:
                    187:        memmove(buf2, ev->region.base, 12);
                    188:        memset(buf2 + 12, 1, 4);
                    189:        buf2[2] |= 0x80;        /* qr=1 */
                    190:
                    191:        /*
                    192:         * send message to be discarded.
                    193:         */
                    194:        region.base = buf1;
                    195:        region.length = sizeof(buf1);
                    196:        dummy = NULL;
                    197:        isc_socket_attach(sock, &dummy);
                    198:        result = isc_socket_sendto(sock, &region, task, senddone, sock,
                    199:                                   &ev->address, NULL);
                    200:        if (result != ISC_R_SUCCESS)
                    201:                isc_socket_detach(&dummy);
                    202:
                    203:        /*
                    204:         * send nextitem message.
                    205:         */
                    206:        region.base = buf2;
                    207:        region.length = sizeof(buf2);
                    208:        dummy = NULL;
                    209:        isc_socket_attach(sock, &dummy);
                    210:        result = isc_socket_sendto(sock, &region, task, senddone, sock,
                    211:                                   &ev->address, NULL);
                    212:        if (result != ISC_R_SUCCESS)
                    213:                isc_socket_detach(&dummy);
                    214:        isc_event_free(&event);
                    215: }
                    216:
                    217: static dns_dispatch_t *dispatch = NULL;
                    218: static dns_dispentry_t *dispentry = NULL;
1.3       christos  219: static bool first = true;
1.1       christos  220: static isc_mutex_t lock;
                    221: static isc_sockaddr_t local;
                    222: static unsigned int responses = 0;
                    223:
                    224: static void
                    225: response(isc_task_t *task, isc_event_t *event) {
                    226:        dns_dispatchevent_t *devent = (dns_dispatchevent_t *)event;
                    227:        isc_result_t result;
1.3       christos  228:        bool wasfirst;
1.1       christos  229:
                    230:        UNUSED(task);
                    231:
                    232:        LOCK(&lock);
                    233:        wasfirst = first;
1.3       christos  234:        first = false;
1.1       christos  235:        responses++;
                    236:        UNLOCK(&lock);
                    237:
                    238:        if (wasfirst) {
                    239:                result = dns_dispatch_getnext(dispentry, &devent);
1.3       christos  240:                assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  241:        } else {
                    242:                dns_dispatch_removeresponse(&dispentry, &devent);
                    243:                isc_app_shutdown();
                    244:        }
                    245: }
                    246:
                    247: static void
                    248: startit(isc_task_t *task, isc_event_t *event) {
                    249:        isc_result_t result;
                    250:        isc_socket_t *sock = NULL;
                    251:
                    252:        isc_socket_attach(dns_dispatch_getsocket(dispatch), &sock);
                    253:        result = isc_socket_sendto(sock, event->ev_arg, task, senddone, sock,
                    254:                                   &local, NULL);
1.3       christos  255:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  256:        isc_event_free(&event);
                    257: }
                    258:
1.3       christos  259: /* test dispatch getnext */
                    260: static void
                    261: dispatch_getnext(void **state) {
1.1       christos  262:        isc_region_t region;
                    263:        isc_result_t result;
                    264:        isc_socket_t *sock = NULL;
                    265:        isc_task_t *task = NULL;
1.3       christos  266:        uint16_t id;
1.1       christos  267:        struct in_addr ina;
                    268:        unsigned char message[12];
                    269:        unsigned int attrs;
                    270:        unsigned char rbuf[12];
                    271:
1.3       christos  272:        UNUSED(state);
1.1       christos  273:
1.3       christos  274:        isc_mutex_init(&lock);
1.1       christos  275:
                    276:        result = isc_task_create(taskmgr, 0, &task);
1.3       christos  277:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  278:
1.3       christos  279:        result = dns_dispatchmgr_create(mctx, &dispatchmgr);
                    280:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  281:
                    282:        ina.s_addr = htonl(INADDR_LOOPBACK);
                    283:        isc_sockaddr_fromin(&local, &ina, 0);
                    284:        attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP;
                    285:        result = dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
                    286:                                     &local, 512, 6, 1024, 17, 19, attrs,
                    287:                                     attrs, &dispatch);
1.3       christos  288:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  289:
                    290:        /*
                    291:         * Create a local udp nameserver on the loopback.
                    292:         */
                    293:        result = isc_socket_create(socketmgr, AF_INET, isc_sockettype_udp,
                    294:                                   &sock);
1.3       christos  295:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  296:
                    297:        ina.s_addr = htonl(INADDR_LOOPBACK);
                    298:        isc_sockaddr_fromin(&local, &ina, 0);
                    299:        result = isc_socket_bind(sock, &local, 0);
1.3       christos  300:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  301:
                    302:        result = isc_socket_getsockname(sock, &local);
1.3       christos  303:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  304:
1.3       christos  305:        first = true;
1.1       christos  306:        region.base = rbuf;
                    307:        region.length = sizeof(rbuf);
                    308:        result = isc_socket_recv(sock, &region, 1, task, nameserver, sock);
1.3       christos  309:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  310:
1.3       christos  311:        result = dns_dispatch_addresponse(dispatch, 0, &local, task, response,
                    312:                                          NULL, &id, &dispentry, NULL);
                    313:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  314:
                    315:        memset(message, 0, sizeof(message));
                    316:        message[0] = (id >> 8) & 0xff;
                    317:        message[1] = id & 0xff;
                    318:
                    319:        region.base = message;
                    320:        region.length = sizeof(message);
                    321:        result = isc_app_onrun(mctx, task, startit, &region);
1.3       christos  322:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  323:
                    324:        result = isc_app_run();
1.3       christos  325:        assert_int_equal(result, ISC_R_SUCCESS);
1.1       christos  326:
1.3       christos  327:        assert_int_equal(responses, 2);
1.1       christos  328:
                    329:        /*
                    330:         * Shutdown nameserver.
                    331:         */
                    332:        isc_socket_cancel(sock, task, ISC_SOCKCANCEL_RECV);
                    333:        isc_socket_detach(&sock);
                    334:        isc_task_detach(&task);
                    335:
                    336:        /*
                    337:         * Shutdown the dispatch.
                    338:         */
                    339:        dns_dispatch_detach(&dispatch);
                    340:        dns_dispatchmgr_destroy(&dispatchmgr);
1.3       christos  341: }
                    342:
                    343: int
                    344: main(void) {
                    345:        const struct CMUnitTest tests[] = {
                    346:                cmocka_unit_test_setup_teardown(dispatchset_create,
                    347:                                                _setup, _teardown),
                    348:                cmocka_unit_test_setup_teardown(dispatchset_get,
                    349:                                                _setup, _teardown),
                    350:                cmocka_unit_test_setup_teardown(dispatch_getnext,
                    351:                                                _setup, _teardown),
                    352:        };
1.1       christos  353:
1.3       christos  354:        return (cmocka_run_group_tests(tests, NULL, NULL));
1.1       christos  355: }
                    356:
1.3       christos  357: #else /* HAVE_CMOCKA */
                    358:
                    359: #include <stdio.h>
                    360:
                    361: int
                    362: main(void) {
                    363:        printf("1..0 # Skipped: cmocka not available\n");
                    364:        return (0);
1.1       christos  365: }
1.3       christos  366:
                    367: #endif

CVSweb <webmaster@jp.NetBSD.org>