adb_test.c revision 1.2.6.1
1/*	$NetBSD: adb_test.c,v 1.2.6.1 2012/06/05 21:15:19 bouyer Exp $	*/
2
3/*
4 * Copyright (C) 2004, 2005, 2007, 2009, 2011  Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2001  Internet Software Consortium.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20/* Id: adb_test.c,v 1.73 2011/08/30 23:46:51 tbox Exp  */
21
22/*! \file */
23
24#include <config.h>
25
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29
30#include <isc/app.h>
31#include <isc/buffer.h>
32#include <isc/entropy.h>
33#include <isc/hash.h>
34#include <isc/socket.h>
35#include <isc/task.h>
36#include <isc/timer.h>
37#include <isc/util.h>
38
39#include <dns/adb.h>
40#include <dns/cache.h>
41#include <dns/dispatch.h>
42#include <dns/db.h>
43#include <dns/log.h>
44#include <dns/rootns.h>
45#include <dns/result.h>
46
47typedef struct client client_t;
48struct client {
49	dns_name_t		name;
50	const char	       *target;
51	ISC_LINK(client_t)	link;
52	dns_adbfind_t	       *find;
53};
54
55static isc_mem_t *mctx = NULL;
56static isc_entropy_t *ectx = NULL;
57static isc_mempool_t *cmp;
58static isc_log_t *lctx;
59static isc_logconfig_t *lcfg;
60static isc_taskmgr_t *taskmgr;
61static isc_socketmgr_t *socketmgr;
62static isc_timermgr_t *timermgr;
63static dns_dispatchmgr_t *dispatchmgr;
64static isc_task_t *t1, *t2;
65static dns_view_t *view;
66static dns_db_t *rootdb;
67static ISC_LIST(client_t) clients;
68static isc_mutex_t client_lock;
69static isc_stdtime_t now;
70static dns_adb_t *adb;
71
72static void
73check_result(isc_result_t result, const char *format, ...)
74     ISC_FORMAT_PRINTF(2, 3);
75
76static void
77check_result(isc_result_t result, const char *format, ...) {
78	va_list args;
79
80	if (result == ISC_R_SUCCESS)
81		return;
82
83	va_start(args, format);
84	vfprintf(stderr, format, args);
85	va_end(args);
86	fprintf(stderr, ": %s\n", isc_result_totext(result));
87	exit(1);
88}
89
90static client_t *
91new_client(void) {
92	client_t *client;
93
94	client = isc_mempool_get(cmp);
95	INSIST(client != NULL);
96	dns_name_init(&client->name, NULL);
97	ISC_LINK_INIT(client, link);
98	client->find = NULL;
99
100	return (client);
101}
102
103static void
104free_client(client_t **c) {
105	client_t *client;
106
107	INSIST(c != NULL);
108	client = *c;
109	*c = NULL;
110	INSIST(client != NULL);
111	dns_name_free(&client->name, mctx);
112	INSIST(!ISC_LINK_LINKED(client, link));
113	INSIST(client->find == NULL);
114
115	isc_mempool_put(cmp, client);
116}
117
118static inline void
119CLOCK(void) {
120	RUNTIME_CHECK(isc_mutex_lock(&client_lock) == ISC_R_SUCCESS);
121}
122
123static inline void
124CUNLOCK(void) {
125	RUNTIME_CHECK(isc_mutex_unlock(&client_lock) == ISC_R_SUCCESS);
126}
127
128static void
129lookup_callback(isc_task_t *task, isc_event_t *ev) {
130	client_t *client;
131
132	client = ev->ev_arg;
133	INSIST(client->find == ev->ev_sender);
134
135	printf("NAME %s:\n\tTask %p got event %p type %08x from %p, client %p\n\terr4: %s  err6: %s\n",
136	       client->target,
137	       task, ev, ev->ev_type, client->find, client,
138	       isc_result_totext(client->find->result_v4),
139	       isc_result_totext(client->find->result_v6));
140
141	isc_event_free(&ev);
142	ev = NULL;
143
144	CLOCK();
145
146	dns_adb_dumpfind(client->find, stderr);
147	dns_adb_destroyfind(&client->find);
148
149	ISC_LIST_UNLINK(clients, client, link);
150	free_client(&client);
151
152	CUNLOCK();
153}
154
155static void
156create_managers(void) {
157	isc_result_t result;
158
159	taskmgr = NULL;
160	result = isc_taskmgr_create(mctx, 5, 0, &taskmgr);
161	check_result(result, "isc_taskmgr_create");
162
163	timermgr = NULL;
164	result = isc_timermgr_create(mctx, &timermgr);
165	check_result(result, "isc_timermgr_create");
166
167	socketmgr = NULL;
168	result = isc_socketmgr_create(mctx, &socketmgr);
169	check_result(result, "isc_socketmgr_create");
170
171	dispatchmgr = NULL;
172	result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr);
173	check_result(result, "dns_dispatchmgr_create");
174}
175
176static void
177create_view(void) {
178	dns_cache_t *cache;
179	isc_result_t result;
180
181	/*
182	 * View.
183	 */
184	view = NULL;
185	result = dns_view_create(mctx, dns_rdataclass_in, "_default", &view);
186	check_result(result, "dns_view_create");
187
188	/*
189	 * Cache.
190	 */
191	cache = NULL;
192	result = dns_cache_create(mctx, taskmgr, timermgr, dns_rdataclass_in,
193				  "rbt", 0, NULL, &cache);
194	check_result(result, "dns_cache_create");
195	dns_view_setcache(view, cache);
196	dns_cache_detach(&cache);
197
198	{
199		unsigned int attrs;
200		isc_sockaddr_t any4, any6;
201		dns_dispatch_t *disp4 = NULL;
202		dns_dispatch_t *disp6 = NULL;
203
204		isc_sockaddr_any(&any4);
205		isc_sockaddr_any6(&any6);
206
207		attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP;
208		RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr,
209						  taskmgr, &any4, 512, 6, 1024,
210						  17, 19, attrs, attrs, &disp4)
211			      == ISC_R_SUCCESS);
212		INSIST(disp4 != NULL);
213
214		attrs = DNS_DISPATCHATTR_IPV6 | DNS_DISPATCHATTR_UDP;
215		RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr, socketmgr,
216						  taskmgr, &any6, 512, 6, 1024,
217						  17, 19, attrs, attrs, &disp6)
218			      == ISC_R_SUCCESS);
219		INSIST(disp6 != NULL);
220
221		RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10,
222						      socketmgr,
223						      timermgr, 0,
224						      dispatchmgr,
225						      disp4, disp6) ==
226		      ISC_R_SUCCESS);
227	}
228
229	rootdb = NULL;
230	result = dns_rootns_create(mctx, dns_rdataclass_in, NULL, &rootdb);
231	check_result(result, "dns_rootns_create()");
232	dns_view_sethints(view, rootdb);
233	dns_db_detach(&rootdb);
234
235	dns_view_freeze(view);
236}
237
238static void
239lookup(const char *target) {
240	dns_name_t name;
241	unsigned char namedata[256];
242	client_t *client;
243	isc_buffer_t t, namebuf;
244	isc_result_t result;
245	unsigned int options;
246
247	INSIST(target != NULL);
248
249	client = new_client();
250	isc_buffer_init(&t, target, strlen(target));
251	isc_buffer_add(&t, strlen(target));
252	isc_buffer_init(&namebuf, namedata, sizeof(namedata));
253	dns_name_init(&name, NULL);
254	result = dns_name_fromtext(&name, &t, dns_rootname, 0, &namebuf);
255	check_result(result, "dns_name_fromtext %s", target);
256
257	result = dns_name_dup(&name, mctx, &client->name);
258	check_result(result, "dns_name_dup %s", target);
259
260	options = 0;
261	options |= DNS_ADBFIND_INET;
262	options |= DNS_ADBFIND_INET6;
263	options |= DNS_ADBFIND_WANTEVENT;
264	options |= DNS_ADBFIND_HINTOK;
265	options |= DNS_ADBFIND_GLUEOK;
266	result = dns_adb_createfind(adb, t2, lookup_callback, client,
267				    &client->name, dns_rootname, 0, options,
268				    now, NULL, view->dstport, &client->find);
269	if (result != ISC_R_SUCCESS)
270		printf("DNS_ADB_CREATEFIND -> %s\n", dns_result_totext(result));
271	dns_adb_dumpfind(client->find, stderr);
272
273	if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) {
274		client->target = target;
275		ISC_LIST_APPEND(clients, client, link);
276	} else {
277		printf("NAME %s:  err4 %s, err6 %s\n",
278		       target, isc_result_totext(client->find->result_v4),
279		       isc_result_totext(client->find->result_v6));
280
281		dns_adb_destroyfind(&client->find);
282		free_client(&client);
283	}
284}
285
286int
287main(int argc, char **argv) {
288	isc_result_t result;
289	isc_logdestination_t destination;
290
291	UNUSED(argc);
292	UNUSED(argv);
293
294	dns_result_register();
295	result = isc_app_start();
296	check_result(result, "isc_app_start()");
297
298	isc_stdtime_get(&now);
299
300	result = isc_mutex_init(&client_lock);
301	check_result(result, "isc_mutex_init(&client_lock)");
302	ISC_LIST_INIT(clients);
303
304	/*
305	 * EVERYTHING needs a memory context.
306	 */
307	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
308
309	cmp = NULL;
310	RUNTIME_CHECK(isc_mempool_create(mctx, sizeof(client_t), &cmp)
311		      == ISC_R_SUCCESS);
312	isc_mempool_setname(cmp, "adb test clients");
313
314	result = isc_entropy_create(mctx, &ectx);
315	check_result(result, "isc_entropy_create()");
316	result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
317	check_result(result, "isc_hash_create()");
318
319	result = isc_log_create(mctx, &lctx, &lcfg);
320	check_result(result, "isc_log_create()");
321	isc_log_setcontext(lctx);
322	dns_log_init(lctx);
323	dns_log_setcontext(lctx);
324
325	/*
326	 * Create and install the default channel.
327	 */
328	destination.file.stream = stderr;
329	destination.file.name = NULL;
330	destination.file.versions = ISC_LOG_ROLLNEVER;
331	destination.file.maximum_size = 0;
332	result = isc_log_createchannel(lcfg, "_default",
333				       ISC_LOG_TOFILEDESC,
334				       ISC_LOG_DYNAMIC,
335				       &destination, ISC_LOG_PRINTTIME);
336	check_result(result, "isc_log_createchannel()");
337	result = isc_log_usechannel(lcfg, "_default", NULL, NULL);
338	check_result(result, "isc_log_usechannel()");
339
340	/*
341	 * Set the initial debug level.
342	 */
343	isc_log_setdebuglevel(lctx, 2);
344
345	create_managers();
346
347	t1 = NULL;
348	result = isc_task_create(taskmgr, 0, &t1);
349	check_result(result, "isc_task_create t1");
350	t2 = NULL;
351	result = isc_task_create(taskmgr, 0, &t2);
352	check_result(result, "isc_task_create t2");
353
354	printf("task 1 = %p\n", t1);
355	printf("task 2 = %p\n", t2);
356
357	create_view();
358
359	adb = view->adb;
360
361	/*
362	 * Lock the entire client list here.  This will cause all events
363	 * for found names to block as well.
364	 */
365	CLOCK();
366	lookup("f.root-servers.net.");		/* Should be in hints */
367	lookup("www.iengines.com");		/* should fetch */
368	lookup("www.isc.org");			/* should fetch */
369	lookup("www.flame.org");		/* should fetch */
370	lookup("kechara.flame.org.");		/* should fetch */
371	lookup("moghedien.flame.org.");		/* should fetch */
372	lookup("mailrelay.flame.org.");		/* should fetch */
373	lookup("ipv4v6.flame.org.");		/* should fetch */
374	lookup("nonexistant.flame.org.");	/* should fail to be found */
375	lookup("foobar.badns.flame.org.");	/* should fail utterly (NS) */
376	lookup("i.root-servers.net.");		/* Should be in hints */
377	lookup("www.firstcard.com.");
378	lookup("dns04.flame.org.");
379	CUNLOCK();
380
381	sleep(10);
382
383	dns_adb_dump(adb, stderr);
384
385	sleep(10);
386
387	CLOCK();
388	lookup("f.root-servers.net.");		/* Should be in hints */
389	lookup("www.iengines.com");		/* should fetch */
390	lookup("www.isc.org");			/* should fetch */
391	lookup("www.flame.org");		/* should fetch */
392	lookup("kechara.flame.org.");		/* should fetch */
393	lookup("moghedien.flame.org.");		/* should fetch */
394	lookup("mailrelay.flame.org.");		/* should fetch */
395	lookup("ipv4v6.flame.org.");		/* should fetch */
396	lookup("nonexistant.flame.org.");	/* should fail to be found */
397	lookup("foobar.badns.flame.org.");	/* should fail utterly (NS) */
398	lookup("i.root-servers.net.");		/* Should be in hints */
399	CUNLOCK();
400
401	sleep(20);
402
403	dns_adb_dump(adb, stderr);
404
405	isc_task_detach(&t1);
406	isc_task_detach(&t2);
407
408	isc_mem_stats(mctx, stdout);
409	dns_adb_dump(adb, stderr);
410
411	isc_app_run();
412
413	dns_adb_dump(adb, stderr);
414
415	dns_view_detach(&view);
416	adb = NULL;
417
418	fprintf(stderr, "Destroying socket manager\n");
419	isc_socketmgr_destroy(&socketmgr);
420	fprintf(stderr, "Destroying timer manager\n");
421	isc_timermgr_destroy(&timermgr);
422
423	fprintf(stderr, "Destroying task manager\n");
424	isc_taskmgr_destroy(&taskmgr);
425
426	isc_log_destroy(&lctx);
427
428	isc_hash_destroy();
429	isc_entropy_detach(&ectx);
430
431	isc_mempool_destroy(&cmp);
432	isc_mem_stats(mctx, stdout);
433	isc_mem_destroy(&mctx);
434
435	isc_app_finish();
436
437	return (0);
438}
439