From adde4612541b23d82b00741563ef84cb5192df8c Mon Sep 17 00:00:00 2001 From: Michael Graff Date: Mon, 12 Jul 1999 23:45:54 +0000 Subject: [PATCH] make the TCP dispatch test program. Needs work. --- bin/tests/Makefile.in | 41 ++-- bin/tests/dispatch_tcp_test.c | 416 ++++++++++++++++++++++++++++++++++ 2 files changed, 439 insertions(+), 18 deletions(-) create mode 100644 bin/tests/dispatch_tcp_test.c diff --git a/bin/tests/Makefile.in b/bin/tests/Makefile.in index 4fa9ed07b9..7ac20ceaec 100644 --- a/bin/tests/Makefile.in +++ b/bin/tests/Makefile.in @@ -51,77 +51,82 @@ TARGETS = res_test \ db_test \ compress_test \ mempool_test \ - dispatch_test + dispatch_test \ + dispatch_tcp_test @BIND9_MAKE_RULES@ res_test: res_test.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ res_test.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} lex_test: lex_test.o ${ISCDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ lex_test.o \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${LIBS} name_test: name_test.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ name_test.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} sock_test: sock_test.o ${ISCDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ sock_test.o \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${LIBS} sym_test: sym_test.o ${ISCDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ sym_test.o \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${LIBS} task_test: task_test.o ${ISCDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ task_test.o \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${LIBS} shutdown_test: shutdown_test.o ${ISCDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ shutdown_test.o \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${LIBS} timer_test: timer_test.o ${ISCDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ timer_test.o \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${LIBS} rbt_test: rbt_test.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ rbt_test.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} rdata_test: rdata_test.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ rdata_test.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} rwlock_test: rwlock_test.o ${ISCDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ rwlock_test.o \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${LIBS} wire_test: wire_test.o printmsg.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ wire_test.o printmsg.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} master_test: master_test.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ master_test.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} db_test: db_test.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ db_test.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} compress_test: compress_test.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ compress_test.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} mempool_test: mempool_test.o ${ISCDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ mempool_test.o \ - ${ISCLIBS} ${LIBS} + ${ISCLIBS} ${LIBS} dispatch_test: dispatch_test.o printmsg.o ${ISCDEPLIBS} ${DNSDEPLIBS} ${LIBTOOL} ${CC} ${CFLAGS} -o $@ dispatch_test.o printmsg.o \ - ${DNSLIBS} ${ISCLIBS} ${LIBS} + ${DNSLIBS} ${ISCLIBS} ${LIBS} + +dispatch_tcp_test: dispatch_tcp_test.o printmsg.o ${ISCDEPLIBS} ${DNSDEPLIBS} + ${LIBTOOL} ${CC} ${CFLAGS} -o $@ dispatch_tcp_test.o printmsg.o \ + ${DNSLIBS} ${ISCLIBS} ${LIBS} clean distclean:: rm -f ${TARGETS} diff --git a/bin/tests/dispatch_tcp_test.c b/bin/tests/dispatch_tcp_test.c new file mode 100644 index 0000000000..f422d858c1 --- /dev/null +++ b/bin/tests/dispatch_tcp_test.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 1998, 1999 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "printmsg.h" + +isc_mem_t *mctx; +isc_taskmgr_t *manager; +isc_socketmgr_t *socketmgr; +dns_dispatch_t *disp; +isc_task_t *t0, *t1, *t2; +isc_buffer_t render; +unsigned char render_buffer[1024]; +dns_rdataset_t rdataset; +dns_rdatalist_t rdatalist; + +void got_request(isc_task_t *, isc_event_t *); +void got_response(isc_task_t *, isc_event_t *); +void start_response(void); +static inline void CHECKRESULT(dns_result_t, char *); +void send_done(isc_task_t *, isc_event_t *); +void hex_dump(isc_buffer_t *); + +void +hex_dump(isc_buffer_t *b) +{ + unsigned int len; + isc_region_t r; + + isc_buffer_remaining(b, &r); + + printf("Buffer %p (%p, %d): used region base %p, length %d", + b, b->base, b->length, r.base, r.length); + for (len = 0 ; len < r.length ; len++) { + if (len % 16 == 0) + printf("\n"); + printf("%02x ", r.base[len]); + } + printf("\n"); +} + +static inline void +CHECKRESULT(dns_result_t result, char *msg) +{ + if (result != DNS_R_SUCCESS) { + printf("%s: %s\n", msg, isc_result_totext(result)); + + exit(1); + } +} + +void +my_accept(isc_task_t *task, isc_event_t *ev_in) +{ + isc_socket_newconnev_t *ev = (isc_socket_newconnev_t *)ev_in; + dns_dispentry_t *resp; + + if (ev->result != ISC_R_SUCCESS) { + isc_event_free(&ev_in); + isc_app_shutdown(); + } + + /* + * Create a dispatch context + */ + disp = NULL; + RUNTIME_CHECK(dns_dispatch_create(mctx, ev->newsocket, task, + 512, 6, 1024, 4, &disp) + == ISC_R_SUCCESS); + + resp = NULL; + RUNTIME_CHECK(dns_dispatch_addrequest(disp, task, got_request, NULL, + &resp) + == ISC_R_SUCCESS); + + isc_socket_detach(&ev->newsocket); + + isc_event_free(&ev_in); +} + +void +send_done(isc_task_t *task, isc_event_t *ev_in) +{ + isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; + dns_dispentry_t *resp = (dns_dispentry_t *)ev_in->arg; + + (void)task; + + if (ev->result == ISC_R_SUCCESS) { + printf("Send done (SUCCESS)\n"); + isc_event_free(&ev_in); + return; + } + + CHECKRESULT(ev->result, "send_done got event"); + + isc_event_free(&ev_in); + + printf("--- removing response (FAILURE)\n"); + dns_dispatch_removeresponse(disp, &resp, NULL); + isc_app_shutdown(); +} + +void +start_response(void) +{ + dns_dispentry_t *resp; + dns_messageid_t id; + isc_sockaddr_t from; + dns_message_t *msg; + isc_result_t result; + dns_name_t name; + unsigned char namebuf[255]; + isc_buffer_t target; + isc_buffer_t source; + isc_region_t region; + +#define QUESTION "flame.org." + + isc_buffer_init(&source, QUESTION, strlen(QUESTION), + ISC_BUFFERTYPE_TEXT); + isc_buffer_add(&source, strlen(QUESTION)); + isc_buffer_setactive(&source, strlen(QUESTION)); + isc_buffer_init(&target, namebuf, sizeof(namebuf), + ISC_BUFFERTYPE_BINARY); + dns_name_init(&name, NULL); + result = dns_name_fromtext(&name, &source, dns_rootname, ISC_FALSE, + &target); + CHECKRESULT(result, "dns_name_fromtext()"); + + memset(&from, 0, sizeof(from)); + from.length = sizeof(struct sockaddr_in); +#ifdef ISC_NET_HAVESALEN + from.type.sa.sa_len = sizeof(struct sockaddr_in); +#endif + from.type.sin.sin_port = htons(53); + from.type.sa.sa_family = AF_INET; + RUNTIME_CHECK(isc_inet_aton("204.152.184.97", + &from.type.sin.sin_addr) == 1); + + msg = NULL; + result = dns_message_create(mctx, &msg, DNS_MESSAGE_INTENTRENDER); + CHECKRESULT(result, "dns_message_create()"); + + dns_message_addname(msg, &name, DNS_SECTION_QUESTION); + + rdatalist.rdclass = dns_rdataclass_in; + rdatalist.type = dns_rdatatype_a; + rdatalist.ttl = 0; + ISC_LIST_INIT(rdatalist.rdata); + + dns_rdataset_init(&rdataset); + result = dns_rdatalist_tordataset(&rdatalist, &rdataset); + CHECKRESULT(result, "dns_rdatalist_tordataset()"); + + ISC_LIST_APPEND(name.list, &rdataset, link); + + result = printmessage(msg); + CHECKRESULT(result, "printmessage()"); + + isc_buffer_init(&render, render_buffer, sizeof(render_buffer), + ISC_BUFFERTYPE_BINARY); + result = dns_message_renderbegin(msg, &render); + CHECKRESULT(result, "dns_message_renderbegin()"); + + rdataset.attributes |= DNS_RDATASETATTR_QUESTION; + + result = dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0, 0); + CHECKRESULT(result, "dns_message_rendersection(QUESTION)"); + + result = dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0, 0); + CHECKRESULT(result, "dns_message_rendersection(ANSWER)"); + + result = dns_message_rendersection(msg, DNS_SECTION_ADDITIONAL, 0, 0); + CHECKRESULT(result, "dns_message_rendersection(ADDITIONAL)"); + + result = dns_message_rendersection(msg, DNS_SECTION_AUTHORITY, 0, 0); + CHECKRESULT(result, "dns_message_rendersection(AUTHORITY)"); + + printf("--- adding response\n"); + resp = NULL; + result = dns_dispatch_addresponse(disp, &from, t2, got_response, NULL, + &id, &resp); + CHECKRESULT(result, "dns_dispatch_addresponse"); + + printf("Assigned MessageID %d\n", id); + + msg->opcode = dns_opcode_query; + msg->rcode = dns_rcode_noerror; + msg->flags = DNS_MESSAGEFLAG_RD; + msg->id = id; + + result = dns_message_renderend(msg); + CHECKRESULT(result, "dns_message_renderend"); + + dns_message_destroy(&msg); + + isc_buffer_used(&render, ®ion); + result = isc_socket_sendto(dns_dispatch_getsocket(disp), ®ion, + t2, send_done, resp, &from); + CHECKRESULT(result, "isc_socket_sendto()"); +} + +void +got_response(isc_task_t *task, isc_event_t *ev_in) +{ + dns_dispatchevent_t *ev = (dns_dispatchevent_t *)ev_in; + dns_dispentry_t *resp = ev->sender; + dns_message_t *msg; + isc_result_t result; + + (void)task; + + printf("App: Got response (id %d). Result: %s\n", + ev->id, isc_result_totext(ev->result)); + + msg = NULL; + result = dns_message_create(mctx, &msg, DNS_MESSAGE_INTENTPARSE); + CHECKRESULT(result, "dns_message_create() failed"); + + result = dns_message_parse(msg, &ev->buffer); + CHECKRESULT(result, "dns_message_parse() failed"); + + result = printmessage(msg); + CHECKRESULT(result, "printmessage() failed"); + + dns_message_destroy(&msg); + + printf("--- removing response\n"); + dns_dispatch_removeresponse(disp, &resp, &ev); + + isc_app_shutdown(); +} + +void +got_request(isc_task_t *task, isc_event_t *ev_in) +{ + dns_dispatchevent_t *ev = (dns_dispatchevent_t *)ev_in; + dns_dispentry_t *resp = ev->sender; + static int cnt = 0; + dns_message_t *msg; + dns_result_t result; + + printf("App: Got request. Result: %s\n", + isc_result_totext(ev->result)); + + if (ev->result != DNS_R_SUCCESS) { + printf("Got error, terminating application\n"); + dns_dispatch_removerequest(disp, &resp, &ev); + dns_dispatch_destroy(&disp); + isc_app_shutdown(); + return; + } + + hex_dump(&ev->buffer); + + msg = NULL; + result = dns_message_create(mctx, &msg, DNS_MESSAGE_INTENTPARSE); + CHECKRESULT(result, "dns_message_create() failed"); + + result = dns_message_parse(msg, &ev->buffer); + CHECKRESULT(result, "dns_message_parse() failed"); + + result = printmessage(msg); + CHECKRESULT(result, "printmessage() failed"); + + dns_message_destroy(&msg); + + sleep (1); + printf("App: Ready.\n"); + + cnt++; + switch (cnt) { + case 6: + printf("--- removing request\n"); + dns_dispatch_removerequest(disp, &resp, &ev); + dns_dispatch_destroy(&disp); + isc_app_shutdown(); + break; + + case 3: + printf("--- removing request\n"); + dns_dispatch_removerequest(disp, &resp, &ev); + printf("--- adding request\n"); + RUNTIME_CHECK(dns_dispatch_addrequest(disp, task, got_request, + NULL, &resp) + == DNS_R_SUCCESS); + break; + + default: + dns_dispatch_freeevent(disp, resp, &ev); + break; + } +} + +int +main(int argc, char *argv[]) +{ + isc_socket_t *s0; + isc_sockaddr_t sockaddr; + + (void)argc; + (void)argv; + + RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS); + + /* + * EVERYTHING needs a memory context. + */ + mctx = NULL; + RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); + + dns_result_register(); + + /* + * The task manager is independent (other than memory context) + */ + manager = NULL; + RUNTIME_CHECK(isc_taskmgr_create(mctx, 5, 0, &manager) == + ISC_R_SUCCESS); + + t0 = NULL; + RUNTIME_CHECK(isc_task_create(manager, NULL, 0, &t0) == ISC_R_SUCCESS); + t1 = NULL; + RUNTIME_CHECK(isc_task_create(manager, NULL, 0, &t1) == ISC_R_SUCCESS); + t2 = NULL; + RUNTIME_CHECK(isc_task_create(manager, NULL, 0, &t2) == ISC_R_SUCCESS); + + socketmgr = NULL; + RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS); + + /* + * Open up a random socket. Who cares where. + */ + s0 = NULL; + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.type.sin.sin_family = AF_INET; + sockaddr.type.sin.sin_port = htons(5555); + sockaddr.length = sizeof (struct sockaddr_in); + RUNTIME_CHECK(isc_socket_create(socketmgr, isc_socket_tcp, &s0) == + ISC_R_SUCCESS); + RUNTIME_CHECK(isc_socket_bind(s0, &sockaddr) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_socket_listen(s0, 0) == ISC_R_SUCCESS); + RUNTIME_CHECK(isc_socket_accept(s0, t1, my_accept, NULL) + == ISC_R_SUCCESS); + + isc_app_run(); + + isc_socket_detach(&s0); + + fprintf(stderr, "Destroying socket manager\n"); + isc_socketmgr_destroy(&socketmgr); + + isc_task_shutdown(t0); + isc_task_detach(&t0); + isc_task_shutdown(t1); + isc_task_detach(&t1); + isc_task_shutdown(t2); + isc_task_detach(&t2); + + fprintf(stderr, "Destroying task manager\n"); + isc_taskmgr_destroy(&manager); + + isc_mem_stats(mctx, stderr); + isc_mem_destroy(&mctx); + + isc_app_finish(); + + return (0); +}